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