grammar DGDGrammar
rule source_file ws (inherit ws)* (top_level_decl ws)* end rule inherit ("private" WS)? "inherit" WS (ident WS)? ('object' WS)? string_exp ws ';' <Inherit> end rule top_level_decl data_decl / func_decl end rule ident [a-zA-Z_] [a-zA-Z_0-9]* <Identifier> end rule c_comment '/*' ( !'*/' (. / "\n") )* '*/' end rule preproc_hash_line "\n"? "# " decimal " "+ simple_string (" "+ decimal)? "\n" end rule simple_string '"' ( !["\n\\] . )* '"' <StringLiteral> end rule complex_string '"' ( ((!["\n\\] ) .) / . )+ '"' <StringLiteral> end rule simple_char "'" ((!['\n\\]) .)+ "'" <CharLiteral> end rule complex_char "'" (((!['\n\\]) .) / ("\\" .))+ "'" <CharLiteral> end rule decimal [1-9] [0-9]* <DecimalLiteral> end rule octal '0' [0-7]* <OctalLiteral> end rule hexadecimal '0' [xX] [a-fA-F0-9]+ <HexadecimalLiteral> end rule float ([0-9]+ "." [0-9]+ ([eE] [-+]? [0-9]+)?) <FloatLiteral> / ("." [0-9]+ ([eE] [-+]? [0-9]+)?) <FloatLiteral> / ([0-9]+ [eE] [-+]? [0-9]+) <FloatLiteral> end rule single_WS [ \t\v\f\r\n] / c_comment / preproc_hash_line end rule ws single_WS* end rule WS single_WS+ end rule string simple_string / complex_string end rule string_exp string / '(' ws composite_string ws ')' end rule composite_string string_exp / string_exp '+' composite_string end rule klass (class_spec WS)* class_spec end rule class_spec 'private' / 'static' / 'atomic' / 'nomask' / 'varargs' end rule type_spec 'int' / 'float' / 'string' / 'object' / 'mapping' / 'mixed' / 'void' end rule stars ('*' ws)* end rule formals # If you put these in a different order with '' and 'void' first, parses start failing. That seems bad. formal_list (ws '...')? / '' / 'void' end rule formal_list formal (ws ',' ws formal)* end rule formal class_type data_declarator / ident end rule data_decl class_type WS declarators ws ';' <DataDecl> end rule func_decl class_type WS function_declarator ws compound_statement <FuncDecl> / klass WS function_name ws '(' ws formals ws ')' ws compound_statement <FuncDecl> end rule class_type (class_spec WS)* type_spec / (class_spec WS)* 'object' list_exp end rule data_declarator stars ws ident end rule function_name ident / 'operator' ws '+' / 'operator' ws '-' / 'operator' ws '*' / 'operator' ws '/' / 'operator' ws '%' / 'operator' ws '&' / 'operator' ws '^' / 'operator' ws '|' / 'operator' ws '<' / 'operator' ws '>' / 'operator' ws '>=' / 'operator' ws '<=' / 'operator' ws '<<' / 'operator' ws '>>' / 'operator' ws '~' / 'operator' ws '++' / 'operator' ws '--' / 'operator' ws '[' ws ']' / 'operator' ws '[' ws ']' ws '=' / 'operator' ws '[' ws '..' ws ']' end rule function_declarator stars ws function_name ws '(' ws formals ws ')' end rule declarator function_declarator / data_declarator end rule declarators declarator (ws ',' ws declarator)* end rule locals (ws data_decl ws)* end rule statements (ws statement ws)* end rule statement 'if' ws '(' ws list_exp ws ')' ws statement (WS 'else' statement)? / 'do' WS statement WS 'while' ws '(' ws list_exp ws ')' ws ';' / 'while' ws '(' ws list_exp ws ')' ws statement / 'for' ws '(' ws list_exp? ws ';' ws list_exp? ws ';' ws list_exp? ws ')' ws statement / 'rlimits' ws '(' ws list_exp ws ';' ws list_exp ws ')' ws compound_statement / 'catch' ws compound_statement ws ':' statement / 'catch' ws compound_statement / 'switch' ws '(' ws list_exp ws ')' ws compound_statement / 'case' WS exp ws ':' ws statement / 'case' WS exp ws '..' ws exp ws ':' statement / 'default' ws ':' ws statement / 'goto' WS ident ws ';' / 'break' ws ';' / 'continue' ws ';' / 'return' WS list_exp WS ';' / 'return' ws ';' / ident ws ':' ws statement / # label statement list_exp / compound_statement / ';' end rule compound_statement '{' ws locals ws statements ws '}' end rule function_call ('::' ws function_name) / (ident ws '::' ws function_name) / function_name end rule list_exp exp ws ',' ws list_exp / exp end rule exp cond_exp ws '=' ws exp / cond_exp ws '+=' ws exp / cond_exp ws '-=' ws exp / cond_exp ws '*=' ws exp / cond_exp ws '/=' ws exp / cond_exp ws '%=' ws exp / cond_exp ws '<<=' ws exp / cond_exp ws '>>=' ws exp / cond_exp ws '&=' ws exp / cond_exp ws '^=' ws exp / cond_exp ws '|=' ws exp / cond_exp end rule cond_exp or_exp ws '?' ws list_exp ws ':' ws cond_exp / or_exp end rule or_exp and_exp ws '||' ws or_exp / and_exp end rule and_exp bitor_exp ws '&&' ws and_exp / bitor_exp end rule bitor_exp bitxor_exp ws '|' ws bitor_exp / bitxor_exp end rule bitxor_exp bitand_exp ws '^' ws bitxor_exp / bitand_exp end rule bitand_exp equ_exp ws '&' bitand_exp / equ_exp end rule equ_exp rel_exp ws '==' ws equ_exp / rel_exp ws '!=' ws equ_exp / rel_exp end rule rel_exp shift_exp ws '<' ws rel_exp / shift_exp ws '>' ws rel_exp / shift_exp ws '<=' ws rel_exp / shift_exp ws '>=' ws rel_exp / shift_exp end rule shift_exp add_exp ws '<<' ws shift_exp / add_exp ws '>>' ws shift_exp / add_exp end rule add_exp mult_exp ws '+' ws add_exp / mult_exp ws '-' ws add_exp / mult_exp end rule mult_exp cast_exp ws '*' ws mult_exp / cast_exp ws '/' ws mult_exp / cast_exp ws '%' ws mult_exp / cast_exp end rule cast_exp '(' ws class_type ws stars ws ')' ws cast_exp / prefix_exp end rule prefix_exp '++' ws cast_exp / '--' ws cast_exp / '+' ws cast_exp / '-' ws cast_exp / '!' ws cast_exp / '~' ws cast_exp / postfix_exp end rule postfix_exp exp2 (ws ('++' / '--'))? end rule exp2 exp1 ws '->' ws ident ws '(' ws opt_arg_list ws ')' / exp1 ws '<-' ws string_exp / exp1 ((ws '[' ws list_exp ws ']') / (ws '[' ws (list_exp ws)? '..' ws (list_exp ws)? ']'))* end rule exp1 # This works (for now) with function_call up front, but not when it was lower down... # There's some kind of bad stuff going on with precedence that's causing parse failures. # That's weird, since I assume it should try all combinations/precedences before giving up... function_call ws '(' ws opt_arg_list ws ')' / 'catch' ws '(' list_exp ws ')' / 'new' (WS 'object')? ws string_exp (ws '(' ws opt_arg_list ws ')')? / 'nil' / '(' ws '{' ws opt_arg_list_comma ws '}' ws ')' / '(' ws '[' ws opt_assoc_list_comma ws ']' ws ')' / '::' ws ident / decimal / octal / hexadecimal / simple_char / complex_char / float / string / ident / '(' ws list_exp ws ')' end rule arg_list exp ws ',' ws arg_list / exp end rule opt_arg_list arg_list ws '...' / arg_list? end rule opt_arg_list_comma arg_list ws ',' / arg_list? end rule assoc_list assoc_pair ws ',' ws assoc_list / assoc_pair end rule assoc_pair exp ws ':' ws exp end rule opt_assoc_list_comma assoc_list ws ',' / assoc_list? end
end