id = ('a'..'z')('a'..'z'|'0'..'9'|'_')*;
// A printable character (inside strings)
-ch = ' ' .. '~';
+ch = ' ' ...;
// Literal strings
str = '\'' (ch-'\\'-'\''|'\\'ch)* '\'';
// A char by decimal ascii
ch_dec = '#' ('0'..'9')+ ;
+// A char by hexadecimal ascii
+ch_hex = '#' ('x'|'X') ('0'..'9'|'a'..'z'|'A'..'Z')+ ;
+
// A single-line comment
comment = '//' ch* '\n'?;
-any = '\t'..'~';
+any = '\t' ...;
not_star = any - '*';
not_star_not_slash = not_star - '/';
unknown_keyword = 'A'..'Z'('A'..'Z'|'a'..'z'|'0'..'9'|'_')*;
// Igndored stufs
-blank = '\n' | '\t' | ' ' | comment | ccomment;
+blank = '\r' | '\n' | '\t' | ' ' | comment | ccomment;
Parser
Ignored blank;
Rejected unknown_keyword;
-grammar = 'Grammar' id ';' lexer_part? parser_part?;
+grammar = 'Grammar' id ';' lexer_part? parser_part? tree_part?;
lexer_part = 'Lexer' expr*;
{plus:} re3 '+' |
{shortest:} 'Shortest' '(' re ')' |
{longest:} 'Longest' '(' re ')' |
+ {prefixes:} 'Prefixes' '(' re ')' |
{id:} id |
{par:} '(' re ')' |
{class:} text '.' '.' text |
+ {openclass:} text '.' '.' '.' |
{any:} 'Any' |
+ {end:} 'End' |
{text:} text ;
text {-> re} =
{str:} str |
- {ch_dec:} ch_dec ;
+ {ch_dec:} ch_dec |
+ {ch_hex:} ch_hex ;
parser_part = 'Parser' ign? rej? prod*;
-ign = 'Ignored' id ';' ;
+ign = 'Ignored' elem_list ';' ;
rej = 'Rejected' elem_list ';' ;
-prod = id ptrans? '=' alts ';';
+prod = id ptrans? '=' alts priority* ';';
ptrans = '{' '->' id '}';
atrans = '{' '->' '}';
{ques:} elem '?' |
{plus:} elem '+' |
{empty:} 'Empty' ;
+
+priority =
+ {left:} 'Left' alts |
+ {right:} 'Right' alts |
+ {unary:} 'Unary' alts ;
+
+tree_part = 'Tree' prod*;