antlr.g
来自「SRI international 发布的OAA框架软件」· G 代码 · 共 1,075 行 · 第 1/2 页
G
1,075 行
{behavior.beginChildList();}
( element )+
{behavior.endChildList();}
RPAREN
{ behavior.endTree(); }
;
rootNode
{ Token label = null; }
:
(label=id COLON {checkForMissingEndRule(label);} )?
terminal[label]
// | range[null]
;
ebnf
[ Token label, boolean not ]
: lp:LPAREN
{behavior.beginSubRule(label, lp.getLine(), not);}
(
// 2nd alt and optional branch ambig due to
// linear approx LL(2) issue. COLON ACTION
// matched correctly in 2nd alt.
options {
warnWhenFollowAmbig = false;
}
:
subruleOptionsSpec
( aa:ACTION {behavior.refInitAction(aa);} )?
COLON
| ab:ACTION {behavior.refInitAction(ab);}
COLON
)?
block
RPAREN
( ( QUESTION{behavior.optionalSubRule();}
| STAR {behavior.zeroOrMoreSubRule();;}
| PLUS {behavior.oneOrMoreSubRule();}
)?
( BANG {behavior.noASTSubRule(); } )?
|
IMPLIES {behavior.synPred();}
)
{behavior.endSubRule();}
;
ast_type_spec
returns [ int autoGen ]
{ autoGen = GrammarElement.AUTO_GEN_NONE; }
: ( CARET { autoGen = GrammarElement.AUTO_GEN_CARET; }
| BANG { autoGen = GrammarElement.AUTO_GEN_BANG; }
)?
;
range
[ Token label ]
{
Token trLeft=null;
Token trRight=null;
int autoGen=GrammarElement.AUTO_GEN_NONE;
}
: crLeft:CHAR_LITERAL RANGE crRight:CHAR_LITERAL
( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
{ behavior.refCharRange(crLeft, crRight, label, autoGen, lastInRule()); }
|
(t:TOKEN_REF{trLeft=t;}|u:STRING_LITERAL{trLeft=u;})
RANGE
(v:TOKEN_REF{trRight=v;}|w:STRING_LITERAL{trRight=w;})
autoGen = ast_type_spec
{ behavior.refTokenRange(trLeft, trRight, label, autoGen, lastInRule()); }
;
terminal
[ Token label ]
{
int autoGen=GrammarElement.AUTO_GEN_NONE;
Token args=null;
}
:
cl:CHAR_LITERAL
( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
{behavior.refCharLiteral(cl, label, false, autoGen, lastInRule());}
|
tr:TOKEN_REF
autoGen = ast_type_spec
// Args are only valid for lexer
( aa:ARG_ACTION { args=aa; } )?
{ behavior.refToken(null, tr, label, args, false, autoGen, lastInRule()); }
|
sl:STRING_LITERAL
autoGen = ast_type_spec
{behavior.refStringLiteral(sl, label, autoGen, lastInRule());}
|
wi:WILDCARD
autoGen = ast_type_spec
{behavior.refWildcard(wi, label, autoGen);}
;
notTerminal
[ Token label ]
{ int autoGen=GrammarElement.AUTO_GEN_NONE; }
:
cl:CHAR_LITERAL
( BANG { autoGen = GrammarElement.AUTO_GEN_BANG; } )?
{behavior.refCharLiteral(cl, label, true, autoGen, lastInRule());}
|
tr:TOKEN_REF
autoGen = ast_type_spec
{behavior.refToken(null, tr, label, null, true, autoGen, lastInRule());}
;
/** Match a.b.c.d qualified ids; WILDCARD here is overloaded as
* id separator; that is, I need a reference to the '.' token.
*/
qualifiedID returns [Token qidTok=null]
{
StringBuffer buf = new StringBuffer(30);
Token a;
}
: a=id {buf.append(a.getText());}
( WILDCARD a=id
{buf.append('.'); buf.append(a.getText());}
)*
{
// can use either TOKEN_REF or RULE_REF; should
// really create a QID or something instead.
qidTok = new CommonToken(TOKEN_REF, buf.toString());
qidTok.setLine(a.getLine());
}
;
id
returns [ Token idTok ]
{ idTok = null; }
: a:TOKEN_REF {idTok = a;}
| b:RULE_REF {idTok = b;}
;
class ANTLRLexer extends Lexer;
options {
k=2;
exportVocab=ANTLR;
testLiterals=false;
interactive=true;
}
tokens {
"options";
}
{
/**Convert 'c' to an integer char value. */
public static int escapeCharValue(String cs) {
//System.out.println("escapeCharValue("+cs+")");
if ( cs.charAt(1)!='\\' ) return 0;
switch ( cs.charAt(2) ) {
case 'b' : return '\b';
case 'r' : return '\r';
case 't' : return '\t';
case 'n' : return '\n';
case 'f' : return '\f';
case '"' : return '\"';
case '\'' :return '\'';
case '\\' :return '\\';
case 'u' :
// Unicode char
if (cs.length() != 8) {
return 0;
}
else {
return
Character.digit(cs.charAt(3), 16) * 16 * 16 * 16 +
Character.digit(cs.charAt(4), 16) * 16 * 16 +
Character.digit(cs.charAt(5), 16) * 16 +
Character.digit(cs.charAt(6), 16);
}
case '0' :
case '1' :
case '2' :
case '3' :
if ( cs.length()>5 && Character.isDigit(cs.charAt(4)) ) {
return (cs.charAt(2)-'0')*8*8 + (cs.charAt(3)-'0')*8 + (cs.charAt(4)-'0');
}
if ( cs.length()>4 && Character.isDigit(cs.charAt(3)) ) {
return (cs.charAt(2)-'0')*8 + (cs.charAt(3)-'0');
}
return cs.charAt(2)-'0';
case '4' :
case '5' :
case '6' :
case '7' :
if ( cs.length()>4 && Character.isDigit(cs.charAt(3)) ) {
return (cs.charAt(2)-'0')*8 + (cs.charAt(3)-'0');
}
return cs.charAt(2)-'0';
default :
return 0;
}
}
public static int tokenTypeForCharLiteral(String lit) {
if ( lit.length()>3 ) { // does char contain escape?
return escapeCharValue(lit);
}
else {
return lit.charAt(1);
}
}
}
WS : ( /* '\r' '\n' can be matched in one alternative or by matching
'\r' in one iteration and '\n' in another. I am trying to
handle any flavor of newline that comes in, but the language
that allows both "\r\n" and "\r" and "\n" to all be valid
newline is ambiguous. Consequently, the resulting grammar
must be ambiguous. I'm shutting this warning off.
*/
options {
generateAmbigWarnings=false;
}
: ' '
| '\t'
| '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
)
{ $setType(Token.SKIP); }
;
COMMENT :
( SL_COMMENT | t:ML_COMMENT {$setType(t.getType());} )
{if ( _ttype != DOC_COMMENT ) $setType(Token.SKIP);}
;
protected
SL_COMMENT :
"//"
( ~('\n'|'\r') )*
(
/* '\r' '\n' can be matched in one alternative or by matching
'\r' and then in the next token. The language
that allows both "\r\n" and "\r" and "\n" to all be valid
newline is ambiguous. Consequently, the resulting grammar
must be ambiguous. I'm shutting this warning off.
*/
options {
generateAmbigWarnings=false;
}
: '\r' '\n'
| '\r'
| '\n'
)
{ newline(); }
;
protected
ML_COMMENT :
"/*"
( { LA(2)!='/' }? '*' {$setType(DOC_COMMENT);}
|
)
(
/* '\r' '\n' can be matched in one alternative or by matching
'\r' and then in the next token. The language
that allows both "\r\n" and "\r" and "\n" to all be valid
newline is ambiguous. Consequently, the resulting grammar
must be ambiguous. I'm shutting this warning off.
*/
options {
greedy=false; // make it exit upon "*/"
generateAmbigWarnings=false; // shut off newline errors
}
: '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
| ~('\n'|'\r')
)*
"*/"
;
OPEN_ELEMENT_OPTION
: '<'
;
CLOSE_ELEMENT_OPTION
: '>'
;
COMMA : ',';
QUESTION : '?' ;
TREE_BEGIN : "#(" ;
LPAREN: '(' ;
RPAREN: ')' ;
COLON : ':' ;
STAR: '*' ;
PLUS: '+' ;
ASSIGN : '=' ;
IMPLIES : "=>" ;
SEMI: ';' ;
CARET : '^' ;
BANG : '!' ;
OR : '|' ;
WILDCARD : '.' ;
RANGE : ".." ;
NOT_OP : '~' ;
RCURLY: '}' ;
CHAR_LITERAL
: '\'' (ESC|~'\'') '\''
;
STRING_LITERAL
: '"' (ESC|~'"')* '"'
;
protected
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| 'w'
| 'a'
| '"'
| '\''
| '\\'
| ('0'..'3')
(
options {
warnWhenFollowAmbig = false;
}
:
('0'..'9')
(
options {
warnWhenFollowAmbig = false;
}
:
'0'..'9'
)?
)?
| ('4'..'7')
(
options {
warnWhenFollowAmbig = false;
}
:
('0'..'9')
)?
| 'u' XDIGIT XDIGIT XDIGIT XDIGIT
)
;
protected
DIGIT
: '0'..'9'
;
protected
XDIGIT :
'0' .. '9'
| 'a' .. 'f'
| 'A' .. 'F'
;
protected
VOCAB
: '\3'..'\176' // common ASCII
;
INT : ('0'..'9')+
;
ARG_ACTION
:
NESTED_ARG_ACTION
{ setText(Tool.stripFrontBack(getText(), "[", "]")); }
;
protected
NESTED_ARG_ACTION :
'['
(
/* '\r' '\n' can be matched in one alternative or by matching
'\r' and then '\n' in the next iteration.
*/
options {
generateAmbigWarnings=false; // shut off newline errors
}
: NESTED_ARG_ACTION
| '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
| CHAR_LITERAL
| STRING_LITERAL
| ~']'
)*
']'
;
ACTION
{int actionLine=getLine();}
: NESTED_ACTION
( '?' {_ttype = SEMPRED;} )?
{
if ( _ttype==ACTION ) {
setText(Tool.stripFrontBack(getText(), "{", "}"));
}
else {
setText(Tool.stripFrontBack(getText(), "{", "}?"));
}
CommonToken t = new CommonToken(_ttype,$getText);
t.setLine(actionLine); // set action line to start
$setToken(t);
}
;
protected
NESTED_ACTION :
'{'
(
options {
greedy = false; // exit upon '}'
}
:
(
options {
generateAmbigWarnings = false; // shut off newline warning
}
: '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
)
| NESTED_ACTION
| CHAR_LITERAL
| COMMENT
| STRING_LITERAL
| .
)*
'}'
;
TOKEN_REF
options { testLiterals = true; }
: 'A'..'Z'
( // scarf as many letters/numbers as you can
options {
warnWhenFollowAmbig=false;
}
:
'a'..'z'|'A'..'Z'|'_'|'0'..'9'
)*
;
// we get a warning here when looking for options '{', but it works right
RULE_REF
{
int t=0;
}
: t=INTERNAL_RULE_REF {_ttype=t;}
( {t==LITERAL_options}? WS_LOOP ('{' {_ttype = OPTIONS;})?
| {t==LITERAL_tokens}? WS_LOOP ('{' {_ttype = TOKENS;})?
|
)
;
protected
WS_LOOP
: ( // grab as much WS as you can
options {
greedy=true;
}
:
WS
| COMMENT
)*
;
protected
INTERNAL_RULE_REF returns [int t]
{
t = RULE_REF;
}
: 'a'..'z'
( // scarf as many letters/numbers as you can
options {
warnWhenFollowAmbig=false;
}
:
'a'..'z'|'A'..'Z'|'_'|'0'..'9'
)*
{t = testLiteralsTable(t);}
;
protected
WS_OPT :
(WS)?
;
// remove after the class variants of the scanners/parsers go
// away. this rule, just forces the lexer to use the most
// complicated class so I can get rid of the others.
protected
NOT_USEFUL
: ('a')=>'a'
| 'a'
;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?