// 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'?;
ccomment = '/*' not_star* ('*' (not_star_not_slash not_star*)?)* '*/';
-unknown_keyword = 'A..Z'('A'..'Z'|'a'..'z'|'0'..'9'|'_')*;
+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? reject?;
-
-reject = 'XXX' unknown_keyword ';';
+grammar = 'Grammar' id ';' lexer_part? parser_part? tree_part?;
lexer_part = 'Lexer' expr*;
re1 {-> re} =
{minus:} re1 '-' re2 |
+ {except:} re1 'Except' re2 |
+ {and:} re1 'And' re2 |
re2 ;
re2 {-> re} =
{ques:} re3 '?' |
{star:} re3 '*' |
{plus:} re3 '+' |
+ {shortest:} 'Shortest' '(' re ')' |
+ {longest:} 'Longest' '(' re ')' |
{id:} id |
- {str:} str |
{par:} '(' re ')' |
- {class:} str '.' '.' str |
+ {class:} text '.' '.' text |
{any:} 'Any' |
- {ch_dec:} ch_dec ;
+ {end:} 'End' |
+ {text:} text ;
+
+text {-> re} =
+ {str:} str |
+ {ch_dec:} ch_dec |
+ {ch_hex:} ch_hex ;
+parser_part = 'Parser' ign? rej? prod*;
-parser_part = 'Parser' ign? prod*;
+ign = 'Ignored' elem_list ';' ;
-ign = 'Ignored' id ';' ;
+rej = 'Rejected' elem_list ';' ;
-prod = id ptrans? '=' alts ';';
+prod = id ptrans? '=' alts priority* ';';
ptrans = '{' '->' id '}';
-atrans = '{' '->' id '}';
+atrans = '{' '->' '}';
alts =
{more:} alts '|' alt |
elemid = '[' id ':' ']' | '[' id ']' ':';
+elem_list =
+ {more:} elem_list ',' elem |
+ {one:} elem ;
+
elem =
{id:} id |
- {str:} str |
+ {str:} text |
{star:} elem '*' |
{ques:} elem '?' |
- {plus:} elem '+' ;
+ {plus:} elem '+' |
+ {empty:} 'Empty' ;
+
+priority =
+ {left:} 'Left' alts |
+ {right:} 'Right' alts |
+ {unary:} 'Unary' alts ;
+
+tree_part = 'Tree' prod*;