-
Notifications
You must be signed in to change notification settings - Fork 0
/
peg.peg
127 lines (116 loc) · 5.29 KB
/
peg.peg
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# PE Grammar for PE Grammars
#
# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
#
# Best viewed using 140 columns monospaced with tabs every 8.
#
# [1] Bryan Ford. "Parsing Expression Grammars: A Recognition-Based Syntactic
# Foundation." Symposium on Principles of Programming Languages,
# January 14--16, 2004, Venice, Italy.
package main
import "github.com/panther-labs/peg/tree"
# parser declaration
type Peg Peg {
*tree.Tree
}
# Hierarchical syntax
Grammar <- Spacing 'package' MustSpacing Identifier { p.AddPackage(text) }
Import*
'type' MustSpacing Identifier { p.AddPeg(text) }
'Peg' Spacing Action { p.AddState(text) }
Definition+ EndOfFile
Import <- 'import' Spacing (MultiImport / SingleImport) Spacing
SingleImport <- ImportName
MultiImport <- '(' Spacing (ImportName '\n' Spacing)* Spacing ')'
ImportName <- ["] < [0-9a-zA-Z_/.\-]+ > ["] { p.AddImport(text) }
Definition <- Identifier { p.AddRule(text) }
LeftArrow Expression { p.AddExpression() } &(Identifier LeftArrow / !.)
Expression <- Sequence (Slash Sequence { p.AddAlternate() }
)* (Slash { p.AddNil(); p.AddAlternate() }
)?
/ { p.AddNil() }
Sequence <- Prefix (Prefix { p.AddSequence() }
)*
Prefix <- And Action { p.AddPredicate(text) }
/ Not Action { p.AddStateChange(text) }
/ And Suffix { p.AddPeekFor() }
/ Not Suffix { p.AddPeekNot() }
/ Suffix
Suffix <- Primary (Question { p.AddQuery() }
/ Star { p.AddStar() }
/ Plus { p.AddPlus() }
)?
Primary <- Identifier !LeftArrow { p.AddName(text) }
/ Open Expression Close
/ Literal
/ Class
/ Dot { p.AddDot() }
/ Action { p.AddAction(text) }
/ Begin Expression End { p.AddPush() }
# Lexical syntax
#PrivateIdentifier <- < [a-z_] IdentCont* > Spacing
Identifier <- < IdentStart IdentCont* > Spacing
IdentStart <- [[a-z_]]
IdentCont <- IdentStart / [0-9]
Literal <- ['] (!['] Char)? (!['] Char { p.AddSequence() }
)* ['] Spacing
/ ["] (!["] DoubleChar)? (!["] DoubleChar { p.AddSequence() }
)* ["] Spacing
Class <- ( '[[' ( '^' DoubleRanges { p.AddPeekNot(); p.AddDot(); p.AddSequence() }
/ DoubleRanges )?
']]'
/ '[' ( '^' Ranges { p.AddPeekNot(); p.AddDot(); p.AddSequence() }
/ Ranges )?
']' )
Spacing
Ranges <- !']' Range (!']' Range { p.AddAlternate() }
)*
DoubleRanges <- !']]' DoubleRange (!']]' DoubleRange { p.AddAlternate() }
)*
Range <- Char '-' Char { p.AddRange() }
/ Char
DoubleRange <- Char '-' Char { p.AddDoubleRange() }
/ DoubleChar
Char <- Escape
/ !'\\' <.> { p.AddCharacter(text) }
DoubleChar <- Escape
/ <[a-zA-Z]> { p.AddDoubleCharacter(text) }
/ !'\\' <.> { p.AddCharacter(text) }
Escape <- "\\a" { p.AddCharacter("\a") } # bell
/ "\\b" { p.AddCharacter("\b") } # bs
/ "\\e" { p.AddCharacter("\x1B") } # esc
/ "\\f" { p.AddCharacter("\f") } # ff
/ "\\n" { p.AddCharacter("\n") } # nl
/ "\\r" { p.AddCharacter("\r") } # cr
/ "\\t" { p.AddCharacter("\t") } # ht
/ "\\v" { p.AddCharacter("\v") } # vt
/ "\\'" { p.AddCharacter("'") }
/ '\\"' { p.AddCharacter("\"") }
/ '\\[' { p.AddCharacter("[") }
/ '\\]' { p.AddCharacter("]") }
/ '\\-' { p.AddCharacter("-") }
/ '\\' "0x"<[0-9a-fA-F]+> { p.AddHexaCharacter(text) }
/ '\\' <[0-3][0-7][0-7]> { p.AddOctalCharacter(text) }
/ '\\' <[0-7][0-7]?> { p.AddOctalCharacter(text) }
/ '\\\\' { p.AddCharacter("\\") }
LeftArrow <- ('<-' / '\0x2190') Spacing
Slash <- '/' Spacing
And <- '&' Spacing
Not <- '!' Spacing
Question <- '?' Spacing
Star <- '*' Spacing
Plus <- '+' Spacing
Open <- '(' Spacing
Close <- ')' Spacing
Dot <- '.' Spacing
SpaceComment <- (Space / Comment)
Spacing <- SpaceComment*
MustSpacing <- SpaceComment+
Comment <- ('#' / '//') (!EndOfLine .)* EndOfLine
Space <- ' ' / '\t' / EndOfLine
EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
Action <- '{' < ActionBody* > '}' Spacing
ActionBody <- [^{}] / '{' ActionBody* '}'
Begin <- '<' Spacing
End <- '>' Spacing