1grammar abc::Grammar is HLL::Grammar;
2
3=begin overview
4
5The following is the grammar for abc written as a sequence of
6Perl 6 rules.  In each of the rules, the special notation {*}
7marks a point in the rule where the corresponding action in
8abc::Grammar::Actions is to be invoked (see grammar-actions.pl).
9These actions are then used to construct the ast nodes for
10the program.
11
12The #= markers at the ends of lines are used to distinguish
13among multiple {*} actions within a rule, by passing the value
14after the marker as a 'key' argument to the action method. Note
15that there must be space between the #= marker and the key.
16
17=end overview
18
19rule TOP {
20    ^ <statement_list>
21    [ $ || <panic: 'Syntax error'> ]
22}
23
24rule statement_list {
25    <statement>? [ ';' <statement>? ]*
26}
27
28proto token statement { <...> }
29    # 'break'
30    # 'continue'
31    # 'halt'
32    # 'return' [ '(' <EXPR> ')' ]?
33token statement:sym<expr> { <EXPR> }
34
35
36token statement:sym<if> {
37    <sym> :s '(' <EXPR> ')' <statement> [ 'else' <statement> ]?
38}
39
40
41token statement:sym<while> {
42    <sym> :s '(' <EXPR> ')' <statement>
43}
44
45
46token statement:sym<for> {
47    <sym> :s '(' <EXPR> ';' <EXPR> ';' <EXPR> ')' <statement>
48}
49
50
51token statement:sym<compound> {
52    :s '{' ~ '}' <statement_list>
53}
54
55
56token statement:sym<string> {
57    <.before \"> <quote_EXPR: ':q'>
58}
59
60
61## recognize terms
62
63proto token term { <...> }
64
65
66token term:sym<float> {
67    [
68    | \d+ '.' \d*
69    | '.' \d+
70    ]
71}
72
73token term:sym<int> { \d+ }
74
75token term:sym<variable> {
76    $<name>=[ <[a..z]> <[_a..z0..9]>* ]
77    [ '(' <EXPR> ')' ]?
78}
79
80token term:sym<circumfix> { '(' <.ws> <EXPR> ')' }
81
82# OPS
83
84## autoincrement
85token postfix:sym<++> { <sym> <O('%unary')> }
86token postfix:sym<--> { <sym> <O('%unary')> }
87token prefix:sym<++>  { <sym> <O('%unary')> }
88token prefix:sym<-->  { <sym> <O('%unary')> }
89
90## negation
91token prefix:sym<-> { <sym> <O('%unary, :pirop<neg>')> }
92
93## exponentiation
94token infix:sym<^> { <sym> <O('%exponentiation, :pirop<pow NN>')> }
95
96## multiplicative
97token infix:sym<*> { <sym> <O('%multiplicative, :pirop<mul>')> }
98token infix:sym</> { <sym> <O('%multiplicative, :pirop<div>')> }
99token infix:sym<%> { <sym> <O('%multiplicative, :pirop<mod>')> }
100
101## additive
102token infix:sym<+> { <sym> <O('%additive, :pirop<add>')> }
103token infix:sym<-> { <sym> <O('%additive, :pirop<sub>')> }
104
105## assignment
106token infix:sym<=> { <sym> <O('%assignment, :pasttype<bind>')> }
107
108## relational
109token infix:sym<==> { <sym> <O('%relational, :pirop<iseq INn>')> }
110token infix:sym<!=> { <sym> <O('%relational, :pirop<isne INn>')> }
111token infix:sym«<»  { <sym> <O('%relational, :pirop<islt INn>')> }
112token infix:sym«<=» { <sym> <O('%relational, :pirop<isle INn>')> }
113token infix:sym«>»  { <sym> <O('%relational, :pirop<isgt INn>')> }
114token infix:sym«>=» { <sym> <O('%relational, :pirop<isge INn>')> }
115
116## boolean
117token prefix:sym<!> { <sym> <O('%neg, :pirop<not>')> }
118token infix:sym<&&> { <sym> <O('%and')> }
119token infix:sym<||> { <sym> <O('%or')> }
120
121INIT {
122    NQP::Grammar.O(':prec<y=>, :assoc<unary>', '%unary');
123    NQP::Grammar.O(':prec<w=>, :assoc<left>',  '%exponentiation');
124    NQP::Grammar.O(':prec<u=>, :assoc<left>',  '%multiplicative');
125    NQP::Grammar.O(':prec<t=>, :assoc<left>',  '%additive');
126    NQP::Grammar.O(':prec<m=>, :assoc<right>', '%assignment');
127    NQP::Grammar.O(':prec<n=>, :assoc<non>',   '%relational');
128    NQP::Grammar.O(':prec<o=>, :assoc<unary>',  '%neg');
129    NQP::Grammar.O(':prec<p=>, :assoc<left>',  '%and');
130    NQP::Grammar.O(':prec<q=>, :assoc<left>',  '%or');
131}
132
133## vim: expandtab sw=4 ft=perl6
134