-
Notifications
You must be signed in to change notification settings - Fork 19
/
peggy.peggy
102 lines (78 loc) · 2.2 KB
/
peggy.peggy
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
-- A Parser for peggy itself.
syntax :: Syntax
= definition* !(skip* .)
definition ::: Definition
= ident ":::" haskellType "=" expr { Definition $1 $2 (Token $3) }
/ ident "::" haskellType "=" expr { Definition $1 $2 $3 }
expr :: Expr
= choiceExpr
choiceExpr :: Expr
= (semanticExpr, "/") { Choice $1 }
semanticExpr :: Expr
= sequenceExpr "{" codeFragment "}" { Semantic $1 $2 }
/ sequenceExpr
sequenceExpr :: Expr
= (namedExpr !"::" !"=")+ { Sequence $1 }
namedExpr :: Expr
= ident ":" suffixExpr { Named $1 $2 }
/ suffixExpr
suffixExpr :: Expr
= suffixExpr "*" { Many $1 }
/ suffixExpr "+" { Some $1 }
/ suffixExpr "?" { Optional $1 }
/ prefixExpr
prefixExpr :: Expr
= "&" primExpr { And $1 }
/ "!" primExpr { Not $1 }
/ primExpr
primExpr ::: Expr
= '\"' charLit* '\"' { Terminals True True $1 }
/ '\'' charLit* '\'' { Terminals False False $1 }
/ '[^' range* ']' { TerminalCmp $1 }
/ '[' range* ']' { TerminalSet $1 }
/ "." { TerminalAny }
/ ident { NonTerminal $1 }
/ "(" expr "," expr ")" { SepBy $1 $2 }
/ "(" expr ";" expr ")" { SepBy1 $1 $2 }
/ "(" expr ")"
charLit :: Char
= '\\' escChar
/ ![\'\"] .
escChar :: Char
= 'n' { '\n' }
/ 'r' { '\r' }
/ 't' { '\t' }
/ '\\' { '\\' }
/ '\"' { '\"' }
/ '\'' { '\'' }
/ 'x' hexDigit hexDigit { chr . fst . head . readHex $ [$1, $2] }
range :: CharRange
= rchar '-' rchar { CharRange $1 $2 }
/ rchar { CharOne $1 }
rchar :: Char
= '\\' escChar
/ '\\]' {']'} / '\\[' { '[' } / '\\^' { '^' } / '\\-' { '-' }
/ [^\]]
haskellType :: TermType
= [^=]+
codeFragment :: CodeFragment
= codePart*
codePart :: CodePart
= argument
/ (!'}' !argument .)+ { Snippet $1 }
argument :: CodePart
= '$$' digit+ { AntiArgument $ read $1 }
/ '$' digit+ { Argument $ read $1 }
/ '$' 'p' { ArgPos }
/ '$' 's' { ArgSpan }
digit :: Char = [0-9]
hexDigit :: Char = [0-9a-fA-F]
ident ::: String = [a-z_] [0-9a-zA-Z_]* { $1 : $2 }
skip :: ()
= _:[ \r\n\t] / comment
comment :: ()
= lineComment / regionComment
lineComment :: ()
= '--' _:(!'\n' _:.)* '\n'
regionComment :: ()
= '{-' _:(regionComment / !'-}' _:.)* '-}'