grammar ABC::Grammar is PCT::Grammar; ## an example 'bc' grammar =begin overview The following is the grammar for abc written as a sequence of Perl 6 rules. In each of the rules, the special notation {*} marks a point in the rule where the corresponding action in ABC::Grammar::Actions is to be invoked (see grammar-actions.pl). These actions are then used to construct the ast nodes for the program. The #= markers at the ends of lines are used to distinguish among multiple {*} actions within a rule, by passing the value after the marker as a 'key' argument to the action method. Note that there must be space between the #= marker and the key. =end overview rule TOP { ^ [ $ || ] {*} } rule statement_list { ? [ ';' ? ]* {*} } rule statement { | {*} #= if_statement | {*} #= while_statement | {*} #= for_statement | {*} #= compound_statement | {*} #= string # | 'break' # | 'continue' # | 'halt' # | 'return' [ '(' ')' ]? | {*} #= expression } rule if_statement { 'if' '(' ')' [ 'else' ]? {*} } rule while_statement { 'while' '(' ')' {*} } rule for_statement { 'for' '(' ';' ';' ')' {*} } rule compound_statement { '{' '}' {*} } token string { '"' '"' {*} } ## create operator precedence parser rule 'expression' is optable { ... } ## recognize terms token term { | {*} #= float | {*} #= integer | {*} #= variable } token float { [ | \d+ '.' \d* | '.' \d+ ] {*} } token integer { \d+ {*} } token variable { $=[ <[a..z]> <[_a..z0..9]>* ] [ '(' ')' {*} #= call | <.null> {*} #= var ] } ## terms proto 'term:' is precedence('=') is parsed(&term) { ... } proto circumfix:<( )> is equiv('term:') is pirop('set') { ... } ## autoincrement proto postfix:<++> is looser('term:') is lvalue(1) { ... } proto postfix:<--> is equiv(postfix:<++>) is lvalue(1) { ... } proto prefix:<++> is equiv(postfix:<++>) is lvalue(1) { ... } proto prefix:<--> is equiv(postfix:<++>) is lvalue(1) { ... } ## negation proto prefix:<-> is looser(postfix:<++>) is pirop('n_neg') { ... } ## exponentiation proto infix:<^> is looser(prefix:<->) { ... } ## multiplicative proto infix:<*> is looser(infix:<^>) is pirop('n_mul') { ... } proto infix: is equiv(infix:<*>) is pirop('n_div') { ... } proto infix:<%> is equiv(infix:<*>) is pirop('n_mod') { ... } ## additive proto infix:<+> is looser(infix:<*>) is pirop('n_add') { ... } proto infix:<-> is equiv(infix:<+>) is pirop('n_sub') { ... } ## assignment proto infix:<=> is looser(infix:<+>) is assoc('right') is pasttype('bind') is lvalue(1) { ... } ## relational proto infix:<==> is looser(infix:<=>) is assoc('non') { ... } proto infix: is equiv(infix:<==>) { ... } proto infix:«<» is equiv(infix:<==>) { ... } proto infix:«<=» is equiv(infix:<==>) { ... } proto infix:«>» is equiv(infix:<==>) { ... } proto infix:«>=» is equiv(infix:<==>) { ... } ## boolean proto prefix: is looser(infix:<==>) is pirop('n_not') { ... } proto infix:<&&> is looser(prefix:) is assoc('left') { ... } proto infix:<||> is looser(infix:<&&>) is assoc('left') { ... } ## vim: expandtab sw=4