antlr-based-bootstrap/peg/Grammar.g (100 lines of code) (raw):
grammar Grammar;
options {
language = Java;
output = AST;
ASTLabelType='org.antlr.runtime.tree.CommonTree';
}
tokens {
RULE;
ATTR;
SEQ;
CHOICE;
ATTRS; ATTR;
MODIFIER;
}
@parser::header {
package peg;
}
@lexer::header {
package peg;
}
@members {
// List<CommonTree> myRules = new ArrayList<CommonTree>();
}
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n'? {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '\'' (ESC|~('\''|'\\'))* '\''
| '"' (ESC | ~('\\'|'"'))* '"'
;
fragment
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"'
| '\''
| '\\'
| '>'
| 'u' XDIGIT XDIGIT XDIGIT XDIGIT
| . // unknown, leave as it is
)
;
fragment
DIGIT : '0' .. '9';
XDIGIT :
| 'a' .. 'f'
| 'A' .. 'F'
;
NUMBER : DIGIT+;
OR : '|';
AND : '&';
NOT : '!';
OPT : '?';
ONEMORE : '+';
ZEROMORE: '*';
literal : NUMBER | STRING;
file : (attrs | rule) +;
rule
: modifier* ID '::=' choice attrs? ';'? -> ^(RULE ID modifier* choice attrs?);
// finally {
// myRules.add($rule.tree);
// }
modifier : 'private' -> ^(MODIFIER["private"])
;
attrs :
'{' attr* '}' -> ^(ATTRS attr*)
;
attr : ID '=' value ';'? -> ^(ATTR ID value)
;
value : literal | ID
;
choice
: sequence (OR sequence)* -> ^(CHOICE sequence+);
sequence
: option* -> ^(SEQ option*);
option :
simple quantifier^?
| AND^ simple
| NOT^ simple
;
quantifier
: OPT
| ONEMORE
| ZEROMORE
;
simple : ID
| literal
| '(' choice ')' -> choice;