rule TOP { ^ <statement_list> [ $ || <panic: parse error> ] {*} }

rule statement_list { <statement>? [ ';' <statement>? ]* {*} }

rule statement { | <if_statement> {*} #= if_statement | <while_statement> {*} #= while_statement | <for_statement> {*} #= for_statement | <compound_statement> {*} #= compound_statement | <string> {*} #= string # | 'break' # | 'continue' # | 'halt' # | 'return' [ '(' <expression> ')' ]? | <expression> {*} #= expression }

rule if_statement { 'if' '(' <expression> ')' <statement> [ 'else' <statement> ]? {*} }

rule while_statement { 'while' '(' <expression> ')' <statement> {*} }

rule for_statement { 'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement> {*} }

rule compound_statement { '{' <statement_list> '}' {*} }

token string { '"' <string_literal: "> '"' {*} }

## create operator precedence parser rule 'expression' is optable { ... }

## recognize terms token term { | <float> {*} #= float | <integer> {*} #= integer | <variable> {*} #= variable }

token float { [ | \d+ '.' \d* | '.' \d+ ] {*} }

token integer { \d+ {*} }

token variable { $<name>=[ <[a..z]> <[_a..z0..9]>* ] [ '(' <expression> ')' {*} #= 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


parrot