/
Grammar.pm
92 lines (68 loc) · 2.5 KB
/
Grammar.pm
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
=begin overview
This is the grammar for cish in Perl 6 rules.
=end overview
grammar cish::Grammar is HLL::Grammar;
token TOP {
<statement>*
[ $ || <.panic: "Syntax error"> ]
}
## Lexer items
# This <ws> rule treats /* this as a comment */
token ws {
<!ww>
[ '/*' .*? '*/' | \s+ ]*
}
## Statements
rule statement {
<block> | <control> | <simple> ';'
}
proto token control { <...> }
rule control:sym<while> { <sym> '(' <EXPR> ')' <statement> }
rule control:sym<if> {
<sym> '(' <EXPR> ')' <statement> [ 'else' : <statement> ]?
}
rule block { '{' <statement>* '}' }
rule simple {
| <builtin>
| <EXPR>
| <?>
}
proto token builtin { <...> }
rule builtin:sym<say> { <sym> [ <EXPR> ] ** ',' }
rule builtin:sym<print> { <sym> [ <EXPR> ] ** ',' }
## Terms
token term:sym<integer> { <integer> }
token term:sym<quote> { <quote> }
proto token quote { <...> }
token quote:sym<'> { <?[']> <quote_EXPR: ':q'> } #'
token quote:sym<"> { <?["]> <quote_EXPR: ':qq'> }
## Operators
INIT {
cish::Grammar.O(':prec<v>, :assoc<unary>', '%unary');
cish::Grammar.O(':prec<u>, :assoc<left>', '%multiplicative');
cish::Grammar.O(':prec<t>, :assoc<left>', '%additive');
cish::Grammar.O(':prec<s>, :assoc<left>', '%comparison');
cish::Grammar.O(':prec<r>, :assoc<left>', '%and');
cish::Grammar.O(':prec<q>, :assoc<left>', '%or');
cish::Grammar.O(':prec<p>, :assoc<right>', '%ternary');
}
token circumfix:sym<( )> { '(' <.ws> <EXPR> ')' }
token prefix:sym<-> { <sym> <O('%unary, :pirop<neg>')> }
token prefix:sym<!> { <sym> <O('%unary, :pirop<not>')> }
token infix:sym<%> { <sym> <O('%multiplicative, :pirop<mod>')> }
token infix:sym<*> { <sym> <O('%multiplicative, :pirop<mul>')> }
token infix:sym</> { <sym> <O('%multiplicative, :pirop<div>')> }
token infix:sym<+> { <sym> <O('%additive, :pirop<add>')> }
token infix:sym<-> { <sym> <O('%additive, :pirop<sub>')> }
token infix:sym('<' ) { <sym> <O('%comparison, :pirop<islt IPP>')> }
token infix:sym('<=') { <sym> <O('%comparison, :pirop<isle IPP>')> }
token infix:sym('==') { <sym> <O('%comparison, :pirop<iseq IPP>')> }
token infix:sym('!=') { <sym> <O('%comparison, :pirop<isne IPP>')> }
token infix:sym('>=') { <sym> <O('%comparison, :pirop<isge IPP>')> }
token infix:sym('>' ) { <sym> <O('%comparison, :pirop<isgt IPP>')> }
token infix:sym<&&> { <sym> <O('%and, :pirop<and PPP>')> }
token infix:sym<||> { <sym> <O('%or, :pirop<or PPP>')> }
token infix:sym<? :> {
'?' <EXPR('p')> ':'
<O('%ternary, :pasttype<if>, :reducecheck<ternary>')>
}