grammar = - ( d:definition { global yysval = d; } | end-of-file { global yysval = nil; } ) definition = i:identifier ASSIGN e:expression SEMI? { $$ = Definition.new(name: i, expression: e); } expression = s:sequence !BAR { $$ = s; } | s1:sequence { s1 = Alternation.new().push(s1); } ( BAR s2:sequence { s1.push(s2); } ) * { $$ = s1; } startSequence = - s:sequence { global yysval = s; } sequence = p:prefix ( q:prefix { p = Sequence.new().push(p).push(q); } ( q:prefix { p.push(q); } ) * ) ? { $$ = p; } prefix = AND a:action { $$ = ParseTimeAction.new(action: a); } | AT a:action { $$ = ExecuteAction.new(action: a); } | ( AND s:suffix { $$ = And.new(expression: s); } | NOT s:suffix { $$ = Not.new(expression: s); } | s:suffix { $$ = s; } ) suffix = p:primary ( QUERY { p = Optional.new(expression: p); } | STAR { p = Star.new(expression: p); } | PLUS { p = Plus.new(expression: p); } ) ? { $$ = p; } primary = i1:identifier COLON i2:ruleCall !ASSIGN { $$ = Assignment.new(name: i1, rule: i2); } | i:ruleCall !ASSIGN { $$ = i; } | LPAREN e:expression RPAREN { $$ = e; } | l:literal { $$ = l; } | c:class { $$ = c; } | DOT { $$ = Dot.new(); } | a:action { $$ = a; } | BEGIN e:expression END { $$ = Capture.new(expression: e); } identifier = < [-a-zA-Z_][-a-zA-Z_0-9]* > - { $$ = intern(yytext); } ruleCall = n:identifier CCOLON r:identifier { $$ = NamespacedRuleCall .new(namespace: GetVar.new(name: n).__eval__(), name: r); } | i:identifier { $$ = RuleCall.new(name: i); } literal = ['] < ( !['] char )* > ['] - { $$ = StringLiteral.new(string: yytext.unescaped()); } | ["] < ( !["] char )* > ["] - { $$ = StringLiteral.new(string: yytext.unescaped()); } class = '[' < ( !']' range )* > ']' - { $$ = CharacterClass.new(value: yytext.unescaped()); } range = char '-' char | char char = '\\' [abefnrtv'"\[\]\\] | '\\' [0-3][0-7][0-7] | '\\' [0-7][0-7]? | !'\\' . action = m:metaGrammar::block - { $$ = Action.new(parseTree: Block.new(body: m)); } - = ( space | comment )* space = ' ' | '\t' | end-of-line comment = '#' ( !end-of-line . )* end-of-line end-of-line = '\r\n' | '\n' | '\r' end-of-file = !. BAR = '|' - NOT = '!' - QUERY = '?' - BEGIN = '<' - END = '>' - SEMI = ";" - CCOLON = "::" - LPAREN = "(" - RPAREN = ")" - ASSIGN = "=" ![=] - AND = "&" ![&=] - PLUS = "+" ![+=] - STAR = "*" ![=] - DOT = "." ![.] - COLON = ":" ![:] - AT = "@" -