parrotcode: Untitled | |
Contents | Language Implementations | Cardinal |
grammar cardinal::Grammar is PCT::Grammar;
token TOP { <comp_stmt> [ $ || <panic: Syntax error> ] {*} }
token comp_stmt { {*} #= open <stmts> {*} #= close }
rule stmts { <.term>?[ <stmt> <.term>+]* {*} }
token term { \n | ';' }
token basic_stmt { | <alias> {*} #= alias | <return_stmt> {*} #= return_stmt | <expr> {*} #= expr | <begin> {*} #= begin | <end> {*} #= end }
token return_stmt { 'return' <.ws> <call_args> {*} }
rule alias { 'alias' <fname> <fname> {*} }
token stmt { <basic_stmt> <.ws> <stmt_mod>* {*} }
token stmt_mod { $<sym>=[if|while|unless|until] <.ws> <expr> {*} }
rule expr { <basic_expr> [$<op>=['and'|'or'] <expr>]? {*} }
token basic_expr { | <assignment> {*} #= assignment | <arg> {*} #= arg | <not_expr> {*} #= not_expr }
rule not_expr { 'not' <expr> {*} }
rule begin { 'BEGIN' '{' <comp_stmt> '}' {*} }
rule end { 'END' '{' <comp_stmt> '}' {*} }
rule assignment { <mlhs=lhs> '=' <mrhs=arg> #XXX need to figure out multiple assignment {*} }
rule mlhs { | <lhs> {*} #= lhs | '(' <mlhs> ')' {*} #= mlhs }
token lhs { | <variable> {*} #= variable | <indexed_variable> {*} #= indexed_variable | <member_variable> {*} #= member_variable }
rule indexed_variable { <primary> '[' <args>? ']' {*} }
token member_variable { <primary> '.' <identifier> {*} }
token command { | <call> {*} #= call | <super_call> {*} #= super_call }
rule call { [ <primary=variable> $<dot>=['.'|'::'] ]? <operation> <call_args> <do_block>? {*} }
rule do_block { 'do' <do_args> <.term>? <comp_stmt> 'end' {*} }
rule super_call { 'super' <call_args> {*} }
rule not_command { '!' <command> {*} }
token operation { <.identifier> ('!'|'?')? }
token call_args { | '()' {*} | <args> {*} | '(' <.ws> <args> <.ws> ')' {*} }
rule do_args { '|' [ <identifier> [',' <identifier>]*]?'|' {*} }
token variable { | <varname> {*} #= varname | 'nil' #= nil | 'self' #= self }
token varname { <!reserved_word> [ <global> {*} #= global | <instance_variable> {*} #= instance_variable | <local_variable> {*} #= local_variable ] }
token mrhs { <args> {*} }
rule args { <arg> [',' <arg>]* {*} }
rule 'arg' is optable { ... }
proto 'infix:=' is precedence('1') is pasttype('copy') is lvalue(1) { ... }
token basic_primary { | <literal> {*} #= literal | <command> {*} #= command | <not_command> {*} #= command | <variable> {*} #= variable | <array> {*} #= array | <ahash> {*} #= ahash | <functiondef> {*} #= functiondef | <if_stmt> {*} #= if_stmt | <while_stmt> {*} #= while_stmt | <unless_stmt> {*} #= unless_stmt | <module> {*} #= module | <begin_end> {*} #= begin_end | <pcomp_stmt> {*} #= pcomp_stmt | <scope_identifier> {*} #= scope_identifier }
rule primary { <basic_primary> <post_primary_expr>* {*} }
rule post_primary_expr { | <scope_identifier> {*} #= scope_identifier | '[' <args>? ']' {*} #= args }
rule scope_identifier { '::' <identifier> {*} }
rule pcomp_stmt { '(' <comp_stmt> ')' {*} }
rule if_stmt { 'if' <expr> <.then> <comp_stmt> ['elsif' <expr> <.then> <comp_stmt>]* <else>? 'end' {*} }
token then { ':' | 'then' | <term> ['then']? }
rule while_stmt { $<sym>=['while'|'until'] <expr> <.do> <comp_stmt> 'end' {*} }
rule do { ':' | 'do' | <term> ['do']? }
rule unless_stmt { 'unless' <expr> <.then> <comp_stmt> <else>? 'end' {*} }
rule else { 'else' <comp_stmt> {*} }
rule ensure { 'ensure' <comp_stmt> {*} }
rule rescue { # XXX check <args> ['rescue' <args> <.then> <comp_stmt>]+ {*} }
rule module { 'module' <module_identifier> <comp_stmt> 'end' {*} }
rule functiondef { 'def' <fname> <argdecl> <comp_stmt> 'end' {*} }
rule bodystmt { <comp_stmt> <rescue>? <else>? <ensure>? }
rule argdecl { ['(' [ <identifier> [',' <identifier>]* [',' <slurpy_param>]? [',' <block_param>]? | <slurpy_param> [',' <block_param>]? | <block_param>? ] ')']? {*} }
token slurpy_param { '*' <identifier> {*} }
token block_param { '&' <identifier> {*} }
rule begin_end { 'begin' <comp_stmt> ['rescue' <args>? <.do> <comp_stmt>]+ ['else' <comp_stmt>]? ['ensure' <comp_stmt>]? 'end' {*} }
token fname { <.identifier> }
rule array { '[' [ <args> [',']? ]? ']' {*} }
rule ahash { '{' [ [ <args> | <assocs> ] [',']? ]? '}' {*} }
rule assocs { <assoc> [',' <assoc>]* {*} }
rule assoc { <arg> '=>' <arg> {*} }
token identifier { <!reserved_word> <ident> {*} }
token module_identifier { <before <[A..Z]>> <ident> {*} }
token global { '$' <ident> {*} }
token instance_variable { '@' <ident> {*} }
token class_variable { '@@' <ident> {*} }
token local_variable { <before <[a..z_]>> <ident> {*} }
token constant_variable { <before <[A..Z]>> <ident> {*} }
token literal { | <float> {*} #= float | <integer> {*} #= integer | <string> {*} #= string }
token float { \d* '.' \d+ {*} }
token integer { \d+ {*} }
token string { [ \' <string_literal: "'"> \' | \" <string_literal: '"'> \" ] {*} }
token reserved_word { [alias|and|BEGIN|begin|break|case |class|def|defined|do|else|elsif |END|end|ensure|false|for|if |in|module|next|nil|not|or |redo|rescue|retry|return|self|super |then|true|undef|unless|until|when |while|yield|__FILE__|__LINE__]>> }
token ws { | '\\' \n ## a backslash at end of line | <after [','|'='|'+']> \n ## a newline after a comma or operator is ignored | \h* ['#' \N* \n*]? }
proto 'infix:=' is precedence('1') is pasttype('copy') is lvalue(1) { ... }
proto 'prefix:defined?' is looser('infix:=') { ... }
proto 'infix:+=' is equiv('infix:=') is pirop('add') { ... }
proto 'infix:-=' is equiv('infix:=') is pirop('sub') { ... }
proto 'infix:/=' is equiv('infix:=') is pirop('div') { ... }
proto 'infix:*=' is equiv('infix:=') is pirop('mul') { ... }
proto 'infix:%=' is equiv('infix:=') is pirop('mul') { ... }
proto 'infix:|=' is equiv('infix:=') { ... }
proto 'infix:&=' is equiv('infix:=') { ... }
proto 'infix:~=' is equiv('infix:=') { ... }
proto infix:«>>=» is equiv('infix:=') is pirop('rsh') { ... }
proto infix:«<<=» is equiv('infix:=') is pirop('lsh') { ... }
proto 'infix:&&=' is equiv('infix:=') is pirop('and') { ... }
proto 'infix:**=' is equiv('infix:=') is pirop('pow') { ... }
proto 'ternary:? :' is tighter('infix:=') is pirop('if') { ... }
proto 'infix:..' is tighter('ternary:? :') is pirop('n_add') { ... }
proto 'infix:...' is equiv('infix:...') { ... }
proto 'infix:||' is tighter('infix:..') is past('unless') { ... }
proto 'infix:&&' is tighter('infix:||') is past('if') { ... }
proto 'infix:==' is tighter('infix:&&') { ... } 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:==') { ... }
proto 'infix:«<=»' is tighter('infix:===') { ... } proto infix:«=>» is tighter('infix:===') { ... } proto infix:«>» is tighter('infix:===') { ... } proto infix:«<» is tighter('infix:===') { ... }
proto 'infix:|' is tighter('infix:«<=»') { ... } proto 'infix:^' is equiv('infix:|') { ... }
proto 'infix:&' is tighter('infix:|') { ... }
proto infix:«<<» is tighter('infix:&') { ... } proto infix:«>>» is equiv(infix:«<<») { ... }
proto 'infix:+' is tighter(infix:«<<») is pirop('n_add') { ... }
proto 'infix:-' is equiv('infix:+') is pirop('n_sub') { ... }
proto 'infix:*' is tighter('infix:+') is pirop('n_mul') { ... }
proto 'infix:/' is equiv('infix:*') is pirop('n_div') { ... }
proto 'infix:%' is equiv('infix:*') is pirop('n_mod') { ... }
#proto 'prefix:+' is tighter('infix:*') { ... } #proto 'prefix:-' is equiv('prefix:+') { ... } #proto 'prefix:!' is equiv('prefix:+') { ... } #proto 'prefix:~' is equiv('prefix:+') { ... }
proto 'term:' is tighter('infix:*') is parsed(&primary) { ... }
|