-
Notifications
You must be signed in to change notification settings - Fork 0
/
parc.grammar
112 lines (85 loc) · 2.73 KB
/
parc.grammar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
--
-- This is the complete PARC grammar. It is a PARC grammar that describes the PARC grammar.
--
--
-- Comments start with double hyphen -- and last to the end of line. There are no multi-line comments.
--
"parc" { -- Define package "parc"
"white-space" "ignore" ; -- The lexical analysis will disregard, all white-space tokens.
--
-- Tokens are identifiers that lead with a lower case letter
--
globalIdentifier = "A" - "Z" ( "A" - "Z" | "a" - "z" | "0" - "9" ) *
;
localIdentifier = "a" - "z" ( "A" - "Z" | "a" - "z" | "0" - "9" ) *
;
-- Tokens do not support projections, regex "(\\\\|\\"|[^\\"])*"
literal = "\"" ( "\\\\" | "\\\"" | ^ "\"" )* "\""
;
many = "*" ;
manyAtLeastOnce = "+" ;
manyOptional = "?" ;
--
-- Productions are identifiers that lead with a upper case letter
--
-- The Main production is the entry point to your grammar.
-- A PARC grammar is not required to define a Main production.
Main
= a : Package* => Grammar { PackageList = a }
;
Package
= a : literal "{" b : ( Option | Token | Production ) * "}"
=> Package{ PackageName = a, Content = b }
;
Option
= a : literal b : literal ";"
=> Option{ Name = a, Value = b }
Token
= a : localIdentifier "=" b : TokenRep Projection? ";"
=> Token{ id = a, def = b }
;
TokenRep
= TokenDef
| a : TokenDef b : (many | manyAtLeastOnce | manyOptional)? => TokenRepetition{ Pattern = a, Kind = b }
;
TokenDef
= TokenPrimary
| a:TokenPrimary ( "|" a:TokenDef )+ => Any{ Left = a }
| "(" a : TokenDef ")" => Eval{ Expression = a }
;
TokenPrimary
= a : literal => TokenLiteral{ value = a }
| "^" a : literal => TokenNegative{ value = a }
| a : literal "-" b : literal => TokenRange{ min = a, max = b }
;
Projection
= "=>" a : globalIdentifier "{" b : InitializerList "}" => Projection{ InitializerList = b }
| "=>" b : localIdentifier => LocalProjection{ Local = b }
;
InitializerList
= a : Initializer ("," a:Initializer)* => a
;
Initializer
= a : globalIdentifier "=" b : localIdentifier => Initializer{ Member = a, Local = b }
;
Production
= a : globalIdentifier "=" (b : Rule)+ => Production{ Name = a, Rules = b }
;
Rule
= a : localIdentifier ":" b:AnonymousRule => NamedRule{ Name = a, Rule = b }
| AnonymousRule
;
AnonymousRule
= a:PrimaryRule
| a:PrimaryRule (b:many | b:manyAtLeastOnce | b:manyOptional) => RepetitionRule{ Rule = a, Kind = b }
| a:PrimaryRule "|" b:AnonymousRule => ChoiceRule{ Left = a, Right = b }
;
PrimaryRule
= a : literal => LiteralRule{ Literal = a }
| a : localIdentifier => TokenRule{ Token = a }
| a : globalIdentifier => ProductionRule{ Production = a }
| "(" a:AnonymousRule ")" => EvalRule{ Rule = a }
;
}
-- Notes:
-- There are no reserved keywords.