forked from jasder/antlr
added demo target X.stg
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8729]
This commit is contained in:
parent
4e3fd8446d
commit
c607e66f1a
|
@ -77,7 +77,7 @@ public abstract class Lexer extends Recognizer<LexerInterpreter>
|
|||
/** The token type for the current token */
|
||||
public int type;
|
||||
|
||||
public QStack<Integer> modeStack;
|
||||
public QStack<Integer> modeStack; // TODO: List?
|
||||
public int mode = Lexer.DEFAULT_MODE;
|
||||
|
||||
/** You can set the text for the current token to override what is in
|
||||
|
|
|
@ -0,0 +1,470 @@
|
|||
// DUP OF JAVA JUST TO CHK OTHER TARGET ABILITY
|
||||
javaTypeInitMap ::= [
|
||||
"int":"0",
|
||||
"long":"0",
|
||||
"float":"0.0f",
|
||||
"double":"0.0",
|
||||
"boolean":"false",
|
||||
"byte":"0",
|
||||
"short":"0",
|
||||
"char":"0",
|
||||
default:"null" // anything other than an atomic type
|
||||
]
|
||||
|
||||
// args must be <object-model-object>, <fields-resulting-in-STs>
|
||||
|
||||
ParserFile(file, parser, namedActions) ::= <<
|
||||
// $ANTLR ANTLRVersion> <file.fileName> generatedTimestamp>
|
||||
<namedActions.header>
|
||||
import org.antlr.v4.runtime.NoViableAltException;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.EarlyExitException;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.FailedPredicateException;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
<parser>
|
||||
>>
|
||||
|
||||
Parser(parser, scopes, funcs, atn, actions, sempreds) ::= <<
|
||||
public class <parser.name> extends Parser {
|
||||
public static final int
|
||||
<parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator=", ", wrap, anchor>;
|
||||
public static final String[] tokenNames = {
|
||||
"\<INVALID>", "\<INVALID>", "\<INVALID>",
|
||||
<parser.tokenNames:{k | "<k>"}; separator=", ", wrap, anchor>
|
||||
};
|
||||
public static final String[] ruleNames = {
|
||||
"\<INVALID>",
|
||||
<parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
|
||||
};
|
||||
<scopes>
|
||||
<namedActions.members>
|
||||
<parser:ctor()>
|
||||
<funcs; separator="\n">
|
||||
|
||||
@Override
|
||||
public String[] getTokenNames() { return tokenNames; }
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
<dumpActions(actions,sempreds)>
|
||||
<atn>
|
||||
}
|
||||
>>
|
||||
|
||||
dumpActions(actions,sempreds) ::= <<
|
||||
<if(sempreds)>
|
||||
public boolean sempred(int ruleIndex, int predIndex) {
|
||||
switch ( predIndex ) {
|
||||
<sempreds:{index|
|
||||
case <index> : return <sempreds.(index)>;}; separator="\n">
|
||||
}
|
||||
return true;
|
||||
}
|
||||
<endif>
|
||||
<if(actions)>
|
||||
public void action(int ruleIndex, int actionIndex) {
|
||||
switch ( actionIndex ) {
|
||||
<actions:{index|
|
||||
case <index> : <actions.(index)> break;}; separator="\n">
|
||||
}
|
||||
}
|
||||
<endif>
|
||||
>>
|
||||
|
||||
ctor(p) ::= <<
|
||||
public <p.name>(TokenStream input) {
|
||||
super(input);
|
||||
_interp = new ParserInterpreter(this,_ATN);
|
||||
}
|
||||
>>
|
||||
|
||||
/*
|
||||
// S.g:5:1: b returns [String q, float x] : A ;
|
||||
public final S.b_return b() throws RecognitionException {
|
||||
b_stack.push(new b_scope());
|
||||
S.b_return retval = new S.b_return();
|
||||
*/
|
||||
|
||||
RuleFunction(currentRule,code,decls,context,scope,namedActions,finallyAction) ::= <<
|
||||
<context>
|
||||
<scope>
|
||||
|
||||
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>() throws RecognitionException {
|
||||
_ctx = new ParserRuleContext(_ctx, <currentRule.startState>);
|
||||
ParserRuleContext _thisctx = _ctx;
|
||||
<if(currentRule.scope)>
|
||||
<currentRule.scope.name>_stack.push(new <currentRule.scope.name>());
|
||||
<endif>
|
||||
//System.out.println("enter "+ruleNames[<currentRule.index>]);
|
||||
<currentRule.globalScopesUsed:{s | <s>_stack.push(new <s>());}; separator="\n">
|
||||
<namedActions.init>
|
||||
<decls; separator="\n">
|
||||
try {
|
||||
<code>
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
reportError(re);
|
||||
recover();
|
||||
}
|
||||
finally {
|
||||
<namedActions.after>
|
||||
<currentRule.globalScopesUsed:{s | <s>_stack.pop();}; separator="\n">
|
||||
<if(currentRule.scope)><currentRule.scope.name>_stack.pop();<endif>
|
||||
<finallyAction>
|
||||
_ctx = (ParserRuleContext)_ctx.parent;
|
||||
//System.out.println("exit "+ruleNames[<currentRule.index>]);
|
||||
}
|
||||
return _thisctx;
|
||||
}
|
||||
>>
|
||||
|
||||
CodeBlock(c, ops) ::= <<
|
||||
<ops; separator="\n">
|
||||
>>
|
||||
|
||||
LL1AltBlock(choice, alts, error) ::= <<
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1OptionalBlock(choice, alts, error) ::= <<
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
|
||||
<preamble; separator="\n">
|
||||
if ( <expr> ) {
|
||||
<alts; separator="\n">
|
||||
}
|
||||
<!else if ( !(<followExpr>) ) <error>!>
|
||||
>>
|
||||
|
||||
LL1StarBlock(choice, alts, sync) ::= <<
|
||||
<choice.loopLabel>:
|
||||
while (true) {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
<cases(choice.exitLook)>
|
||||
break <choice.loopLabel>;
|
||||
}
|
||||
//<sync>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration, sync) ::= <<
|
||||
<preamble; separator="\n">
|
||||
while ( <loopExpr> ) {
|
||||
<alts; separator="\n">
|
||||
<iteration>
|
||||
//<sync>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1PlusBlock(choice, alts, iteration, loopExpr, sync, error, iterationSync) ::= <<
|
||||
//<sync>
|
||||
do {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
<iteration>
|
||||
//<iterationSync>
|
||||
} while ( <loopExpr> );
|
||||
>>
|
||||
|
||||
LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration,
|
||||
sync, iterationSync) ::=
|
||||
<<
|
||||
//<sync>
|
||||
<preamble; separator="\n">
|
||||
do {
|
||||
<alts; separator="\n">
|
||||
<iteration>
|
||||
// <iterationSync>
|
||||
} while ( <loopExpr> );
|
||||
>>
|
||||
|
||||
// LL(*) stuff
|
||||
|
||||
AltBlock(choice, alts, error) ::= <<
|
||||
switch ( _interp.adaptivePredict(input,<choice.decision>,_ctx) ) {
|
||||
<alts:{alt |
|
||||
case <i>:
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
>>
|
||||
|
||||
OptionalBlock(choice, alts, error) ::= <<
|
||||
switch ( _interp.adaptivePredict(input,<choice.decision>,_ctx) ) {
|
||||
<alts:{alt |
|
||||
case <i>:
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
}
|
||||
>>
|
||||
|
||||
StarBlock(choice, alts, sync) ::= <<
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
while ( _alt<choice.uniqueID>!=<choice.exitAlt> ) {
|
||||
switch ( _alt<choice.uniqueID> ) {
|
||||
<alts:{alt|
|
||||
case <i>:
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
}
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
}
|
||||
>>
|
||||
|
||||
PlusBlock(choice, alts, error) ::= <<
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
do {
|
||||
switch ( _alt<choice.uniqueID> ) {
|
||||
<alts:{alt|
|
||||
case <i>:
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
} while ( _alt<choice.uniqueID>!=<choice.exitAlt> );
|
||||
>>
|
||||
|
||||
Sync(s) ::= "sync(<s.expecting.name>);"
|
||||
|
||||
ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this,_ctx);"
|
||||
|
||||
TestSetInline(s) ::= <<
|
||||
<s.ttypes:{ttype | <s.varName>==<ttype>}; separator=" || ">
|
||||
>>
|
||||
|
||||
cases(ttypes) ::= <<
|
||||
<ttypes:{t | case <t>:}; separator="\n">
|
||||
>>
|
||||
|
||||
InvokeRule(r) ::= <<
|
||||
_ctx.s = <r.stateNumber>;
|
||||
<if(r.labels)><r.labels:{l | <l> = }><endif><r.name>(<r.argExprs:{e| ,<e>}>);
|
||||
>>
|
||||
|
||||
MatchToken(m) ::= <<
|
||||
_ctx.s = <m.stateNumber>;
|
||||
<if(m.labels)><m.labels:{l | <l> = }>(Token)<endif>match(<m.name>);
|
||||
>>
|
||||
|
||||
// ACTION STUFF
|
||||
|
||||
Action(a, chunks) ::= "<chunks>"
|
||||
|
||||
ForcedAction(a, chunks) ::= "<chunks>"
|
||||
|
||||
SemPred(p, chunks) ::= <<
|
||||
if (!(<chunks>)) throw new FailedPredicateException(this, input, "<currentRule.name>", ""<!"<chunks>"!>);
|
||||
>>
|
||||
|
||||
ActionText(t) ::= "<t.text>"
|
||||
ArgRef(a) ::= "_ctx.<a.name>"
|
||||
RetValueRef(a) ::= "_ctx.<a.name>"
|
||||
QRetValueRef(a) ::= "<a.dict>.<a.name>"
|
||||
/** How to translate $tokenLabel */
|
||||
TokenRef(t) ::= "<t.name>"
|
||||
SetAttr(s,rhsChunks) ::= "_ctx.<s.name> = <rhsChunks>;"
|
||||
//SetQAttr(s,rhsChunks) ::= "<s.dict>.<s.name> = <rhsChunks>;"
|
||||
|
||||
TokenPropertyRef_text(t) ::= "(<t.label>!=null?<t.label>.getText():null)"
|
||||
TokenPropertyRef_type(t) ::= "(<t.label>!=null?<t.label>.getType():0)"
|
||||
TokenPropertyRef_line(t) ::= "(<t.label>!=null?<t.label>.getLine():0)"
|
||||
TokenPropertyRef_pos(t) ::= "(<t.label>!=null?<t.label>.getCharPositionInLine():0)"
|
||||
TokenPropertyRef_channel(t) ::= "(<t.label>!=null?<t.label>.getChannel():0)"
|
||||
TokenPropertyRef_index(t) ::= "(<t.label>!=null?<t.label>.getTokenIndex():0)"
|
||||
TokenPropertyRef_tree(t) ::= "<t.label>_tree"
|
||||
TokenPropertyRef_int(t) ::= "(<t.label>!=null?Integer.valueOf(<t.label>.getText()):0)"
|
||||
|
||||
RulePropertyRef_start(r) ::= "(<r.label>!=null?((<file.TokenLabelType>)<r.label>.start):null)"
|
||||
RulePropertyRef_stop(r) ::= "(<r.label>!=null?((<file.TokenLabelType>)<r.label>.stop):null)"
|
||||
RulePropertyRef_tree(r) ::= "(<r.label>!=null?((<file.ASTLabelType>)<r.label>.tree):null)"
|
||||
RulePropertyRef_text(r) ::= "(<r.label>!=null?((TokenStream)input).toString(<r.label>.start,<r.label>.stop):null)"
|
||||
RulePropertyRef_st(r) ::= "(<r.label>!=null?<r.label>.st:null)"
|
||||
|
||||
DynScopeRef(s) ::= "<s.scope>_stack"
|
||||
DynScopeAttrRef(s) ::= "<s.scope>_stack.peek().<s.attr>"
|
||||
DynScopeAttrRef_negIndex(s, indexChunks) ::=
|
||||
"<s.scope>_stack.get(<s.scope>_stack.size()-<indexChunks>-1).<s.attr>"
|
||||
DynScopeAttrRef_index(s, indexChunks) ::=
|
||||
"<s.scope>_stack.get(<indexChunks>).<s.attr>"
|
||||
SetDynScopeAttr(s, rhsChunks) ::=
|
||||
"<s.scope>_stack.peek().<s.attr> =<rhsChunks>;"
|
||||
SetDynScopeAttr_negIndex(s, indexChunks, rhsChunks) ::=
|
||||
"<s.scope>_stack.get(<s.scope>_stack.size()-<indexChunks>-1).<s.attr> =<rhsChunks>;"
|
||||
SetDynScopeAttr_index(s, indexChunks, rhsChunks) ::=
|
||||
"<s.scope>_stack.get(<indexChunks>).<s.attr> =<rhsChunks>;"
|
||||
|
||||
AddToList(a) ::= "<a.listName>.add(<first(a.opWithResultToAdd.labels)>);"
|
||||
|
||||
TokenDecl(t) ::= "Token <t.name>;"
|
||||
TokenTypeDecl(t) ::= "int <t.name>;"
|
||||
TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>();"
|
||||
RuleContextDecl(r) ::= "<r.ctxName> <r.name>;"
|
||||
|
||||
CaptureNextToken(d) ::= "<d.varName> = input.LT(1);"
|
||||
CaptureNextTokenType(d) ::= "<d.varName> = input.LA(1);"
|
||||
|
||||
StructDecl(s,attrs) ::= <<
|
||||
public static class <s.name> extends ParserRuleContext {
|
||||
<attrs:{a | <a>;}; separator="\n">
|
||||
<if(s.ctorAttrs)>
|
||||
public <s.name>(<s.ctorAttrs:{a | <a>,}> LABitSet follow) {
|
||||
super(follow);
|
||||
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
||||
}
|
||||
<endif>
|
||||
};
|
||||
>>
|
||||
|
||||
DynamicScopeStruct(d,attrs) ::= <<
|
||||
public static class <d.name> {
|
||||
<attrs:{a | <a>;}; separator="\n">
|
||||
};
|
||||
public QStack\<<d.name>\> <d.name>_stack = new QStack\<<d.name>\>();
|
||||
>>
|
||||
|
||||
AttributeDecl(d) ::= "<d.decl>"
|
||||
|
||||
DFADecl(dfa) ::= <<
|
||||
// define <dfa.name>
|
||||
>>
|
||||
|
||||
BitSetDecl(b) ::= <<
|
||||
public static final LABitSet <b.name>=new LABitSet(new long[]{<b.hexWords:{it|<it>L};separator=",">}<if(b.fset.EOF)>, true<endif>);
|
||||
>>
|
||||
|
||||
LexerFile(lexerFile, lexer, namedActions) ::= <<
|
||||
// $ANTLR ANTLRVersion> <lexerFile.fileName> generatedTimestamp>
|
||||
<namedActions.header>
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
<lexer>
|
||||
>>
|
||||
|
||||
Lexer(lexer, atn, actions, sempreds) ::= <<
|
||||
public class <lexer.name> extends Lexer {
|
||||
public static final int
|
||||
<lexer.tokens:{k | <k>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>;
|
||||
<lexer.modes:{m| public static final int <m> = <i0>;}; separator="\n">
|
||||
|
||||
public static final String[] tokenNames = {
|
||||
"\<INVALID>", "\<INVALID>", "\<INVALID>",
|
||||
<lexer.tokenNames:{k | "<k>"}; separator=", ", wrap, anchor>
|
||||
};
|
||||
public static final String[] ruleNames = {
|
||||
"\<INVALID>",
|
||||
<lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
|
||||
};
|
||||
|
||||
<namedActions.members>
|
||||
|
||||
public <lexer.name>(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerInterpreter(this,_ATN);
|
||||
}
|
||||
|
||||
public String getGrammarFileName() { return "<lexerFile.fileName>"; }
|
||||
@Override
|
||||
public String[] getTokenNames() { return tokenNames; }
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
<lexer.namedActions.members>
|
||||
|
||||
<dumpActions(actions,sempreds)>
|
||||
<atn>
|
||||
}
|
||||
>>
|
||||
|
||||
|
||||
SerializedATN(model) ::= <<
|
||||
public static final String _serializedATN =
|
||||
"<model.serialized; wrap={"+<\n>"}, anchor>";
|
||||
public static final ATN _ATN =
|
||||
ATNInterpreter.deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
org.antlr.v4.tool.DOTGenerator dot = new org.antlr.v4.tool.DOTGenerator(null);
|
||||
//System.out.println(dot.getDOT(_ATN.decisionToATNState.get(0)));
|
||||
}
|
||||
>>
|
||||
|
||||
actionMethod(name, ruleIndex, actions) ::= <<
|
||||
public void <name>_actions(int action) {
|
||||
System.out.println("exec action "+action);
|
||||
switch ( action ) {
|
||||
<actions:{a |
|
||||
case <i0> :
|
||||
<a>
|
||||
break;
|
||||
}>
|
||||
}
|
||||
}<\n>
|
||||
>>
|
||||
|
||||
sempredMethod(name, ruleIndex, preds) ::= <<
|
||||
public boolean <name>_sempreds(int pred) {
|
||||
switch ( pred ) {
|
||||
<preds:{p |
|
||||
case <i0> :
|
||||
return <p>;
|
||||
}>
|
||||
default : return false;
|
||||
}
|
||||
}<\n>
|
||||
>>
|
||||
|
||||
/** Using a type to init value map, try to init a type; if not in table
|
||||
* must be an object, default value is "null".
|
||||
*/
|
||||
initValue(typeName) ::= <<
|
||||
<javaTypeInitMap.(typeName)>
|
||||
>>
|
||||
|
||||
codeFileExtension() ::= ".java"
|
||||
|
||||
true() ::= "true"
|
||||
false() ::= "false"
|
|
@ -256,7 +256,7 @@ public class Tool {
|
|||
in = new ANTLRFileStream(fileName);
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
errMgr.toolError(ErrorType.CANNOT_OPEN_FILE, fileName, ioe);
|
||||
errMgr.toolError(ErrorType.CANNOT_OPEN_FILE, ioe, fileName);
|
||||
}
|
||||
return load(in);
|
||||
}
|
||||
|
|
|
@ -43,13 +43,13 @@ public class CodeGenerator {
|
|||
}
|
||||
catch (InstantiationException ie) {
|
||||
g.tool.errMgr.toolError(ErrorType.CANNOT_CREATE_TARGET_GENERATOR,
|
||||
targetName,
|
||||
ie);
|
||||
ie,
|
||||
targetName);
|
||||
}
|
||||
catch (IllegalAccessException cnfe) {
|
||||
g.tool.errMgr.toolError(ErrorType.CANNOT_CREATE_TARGET_GENERATOR,
|
||||
targetName,
|
||||
cnfe);
|
||||
cnfe,
|
||||
targetName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,8 @@ public class CodeGenerator {
|
|||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
g.tool.errMgr.toolError(ErrorType.CANNOT_CREATE_TARGET_GENERATOR,
|
||||
language);
|
||||
iae,
|
||||
language);
|
||||
}
|
||||
|
||||
// if ( EMIT_TEMPLATE_DELIMITERS ) {
|
||||
|
@ -145,8 +146,8 @@ public class CodeGenerator {
|
|||
}
|
||||
catch (IOException ioe) {
|
||||
g.tool.errMgr.toolError(ErrorType.CANNOT_WRITE_FILE,
|
||||
fileName,
|
||||
ioe);
|
||||
ioe,
|
||||
fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,6 +163,11 @@ public class ErrorManager {
|
|||
tool.error(new ToolMessage(errorType, args));
|
||||
}
|
||||
|
||||
public void toolError(ErrorType errorType, Throwable e, Object... args) {
|
||||
errors++;
|
||||
tool.error(new ToolMessage(errorType, e, args));
|
||||
}
|
||||
|
||||
public void grammarError(ErrorType etype,
|
||||
String fileName,
|
||||
org.antlr.runtime.Token token,
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
/** Test ANTLRParser's AST construction. Translate to junit tests with:
|
||||
*
|
||||
* $ java org.antlr.v4.gunit.Gen TestASTStructure.gunit
|
||||
*/
|
||||
gunit TestASTStructure;
|
||||
|
||||
@header {package org.antlr.v4.test;}
|
||||
options {
|
||||
adaptor = org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
parser = org.antlr.v4.parse.ANTLRParser;
|
||||
lexer = org.antlr.v4.parse.ANTLRLexer;
|
||||
}
|
||||
|
||||
grammarSpec:
|
||||
"parser grammar P; a : A;"
|
||||
-> (PARSER_GRAMMAR P (RULES (RULE a (BLOCK (ALT A)))))
|
||||
|
||||
<<
|
||||
parser grammar P;
|
||||
options {k=2; output=AST;}
|
||||
scope S {int x}
|
||||
tokens { A; B='33'; }
|
||||
@header {foo}
|
||||
a : A;
|
||||
>>
|
||||
->
|
||||
(PARSER_GRAMMAR P
|
||||
(OPTIONS (= k 2) (= output AST))
|
||||
(scope S {int x})
|
||||
(tokens { A (= B '33'))
|
||||
(@ header {foo})
|
||||
(RULES (RULE a (BLOCK (ALT A)))))
|
||||
|
||||
<<
|
||||
parser grammar P;
|
||||
@header {foo}
|
||||
tokens { A; B='33'; }
|
||||
options {k=2; ASTLabel=a.b.c; output=AST;}
|
||||
scope S {int x}
|
||||
a : A;
|
||||
>>
|
||||
->
|
||||
(PARSER_GRAMMAR P
|
||||
(@ header {foo})
|
||||
(tokens { A (= B '33'))
|
||||
(OPTIONS (= k 2) (= ASTLabel a.b.c) (= output AST))
|
||||
(scope S {int x})
|
||||
(RULES (RULE a (BLOCK (ALT A)))))
|
||||
|
||||
<<
|
||||
parser grammar P;
|
||||
import A=B, C;
|
||||
a : A;
|
||||
>>
|
||||
->
|
||||
(PARSER_GRAMMAR P
|
||||
(import (= A B) C)
|
||||
(RULES (RULE a (BLOCK (ALT A)))))
|
||||
|
||||
delegateGrammars:
|
||||
"import A;" -> (import A)
|
||||
|
||||
rule:
|
||||
"a : A<X,Y=a.b.c>;" ->
|
||||
(RULE a (BLOCK (ALT (A (ELEMENT_OPTIONS X (= Y a.b.c))))))
|
||||
"A : B+;" -> (RULE A (BLOCK (ALT (+ (BLOCK (ALT B))))))
|
||||
|
||||
<<
|
||||
public a[int i] returns [int y]
|
||||
options {backtrack=true;}
|
||||
scope {int ss;}
|
||||
scope S,T;
|
||||
@init {blort}
|
||||
: ID ;
|
||||
>>
|
||||
->
|
||||
(RULE a
|
||||
(RULEMODIFIERS public)
|
||||
int i
|
||||
(returns int y)
|
||||
(OPTIONS (= backtrack true))
|
||||
(scope {int ss;})
|
||||
(scope S T)
|
||||
(@ init {blort})
|
||||
(BLOCK (ALT ID)))
|
||||
|
||||
<<
|
||||
a[int i] returns [int y]
|
||||
@init {blort}
|
||||
scope {int ss;}
|
||||
options {backtrack=true;}
|
||||
scope S,T;
|
||||
: ID;
|
||||
>>
|
||||
->
|
||||
(RULE a int i
|
||||
(returns int y)
|
||||
(@ init {blort})
|
||||
(scope {int ss;})
|
||||
(OPTIONS (= backtrack true))
|
||||
(scope S T)
|
||||
(BLOCK (ALT ID)))
|
||||
|
||||
<<
|
||||
a : ID ;
|
||||
catch[A b] {foo}
|
||||
finally {bar}
|
||||
>>
|
||||
->
|
||||
(RULE a (BLOCK (ALT ID))
|
||||
(catch A b {foo}) (finally {bar}))
|
||||
|
||||
<<
|
||||
a : ID ;
|
||||
catch[A a] {foo}
|
||||
catch[B b] {fu}
|
||||
finally {bar}
|
||||
>>
|
||||
->
|
||||
(RULE a (BLOCK (ALT ID))
|
||||
(catch A a {foo}) (catch B b {fu}) (finally {bar}))
|
||||
|
||||
block:
|
||||
"( ^(A B) | ^(b C) )" -> (BLOCK (ALT ("^(" A B)) (ALT ("^(" b C)))
|
||||
|
||||
alternative:
|
||||
"x+=ID* -> $x*" ->
|
||||
(ALT_REWRITE
|
||||
(ALT (* (BLOCK (ALT (+= x ID)))))
|
||||
(-> (ALT (* (REWRITE_BLOCK (ALT x))))))
|
||||
|
||||
"A -> ..." -> (ALT_REWRITE (ALT A) (-> ...))
|
||||
"A -> " -> (ALT_REWRITE (ALT A) (-> EPSILON))
|
||||
|
||||
"A -> foo(a={x}, b={y})" ->
|
||||
(ALT_REWRITE
|
||||
(ALT A)
|
||||
(-> (TEMPLATE foo (ARGLIST (= a {x}) (= b {y})))))
|
||||
|
||||
"A -> template(a={x}, b={y}) <<ick>>" ->
|
||||
(ALT_REWRITE
|
||||
(ALT A)
|
||||
(-> (TEMPLATE (ARGLIST (= a {x}) (= b {y})) <<ick>>)))
|
||||
|
||||
"A -> ({name})()" -> (ALT_REWRITE (ALT A) (-> (TEMPLATE {name})))
|
||||
|
||||
"A -> {expr}" -> (ALT_REWRITE (ALT A) (-> {expr}))
|
||||
|
||||
<<
|
||||
A -> {p1}? {e1}
|
||||
-> {e2}
|
||||
->
|
||||
>>
|
||||
->
|
||||
(ALT_REWRITE
|
||||
(ALT A)
|
||||
(-> {p1}? {e1})
|
||||
(-> {e2}))
|
||||
|
||||
"A -> A" -> (ALT_REWRITE (ALT A) (-> (ALT A)))
|
||||
|
||||
"a -> a" -> (ALT_REWRITE (ALT a) (-> (ALT a)))
|
||||
|
||||
"a A X? Y* -> A a ^(TOP X)? Y*" ->
|
||||
(ALT_REWRITE
|
||||
(ALT a A (? (BLOCK (ALT X))) (* (BLOCK (ALT Y))))
|
||||
(-> (ALT
|
||||
A a
|
||||
(? (REWRITE_BLOCK (ALT ("^(" TOP X))))
|
||||
(* (REWRITE_BLOCK (ALT Y))))))
|
||||
|
||||
"A -> A[33]" -> (ALT_REWRITE (ALT A) (-> (ALT (A 33))))
|
||||
|
||||
"A -> 'int' ^(A A)*" ->
|
||||
(ALT_REWRITE
|
||||
(ALT A)
|
||||
(-> (ALT 'int' (* (REWRITE_BLOCK (ALT ("^(" A A)))))))
|
||||
|
||||
<<
|
||||
A -> {p1}? A
|
||||
-> {p2}? B
|
||||
->
|
||||
>>
|
||||
->
|
||||
(ALT_REWRITE (ALT A)
|
||||
(-> {p1}? (ALT A))
|
||||
(-> {p2}? (ALT B))
|
||||
(-> EPSILON))
|
||||
|
||||
element:
|
||||
"b+" -> (+ (BLOCK (ALT b)))
|
||||
"(b)+" -> (+ (BLOCK (ALT b)))
|
||||
"b?" -> (? (BLOCK (ALT b)))
|
||||
"(b)?" -> (? (BLOCK (ALT b)))
|
||||
"(b)*" -> (* (BLOCK (ALT b)))
|
||||
"b*" -> (* (BLOCK (ALT b)))
|
||||
"'while'*" -> (* (BLOCK (ALT 'while')))
|
||||
"'a'+" -> (+ (BLOCK (ALT 'a')))
|
||||
"a[3]" -> (a 3)
|
||||
"'a'..'z'+" -> (+ (BLOCK (ALT (.. 'a' 'z'))))
|
||||
"x=ID" -> (= x ID)
|
||||
"x=ID?" -> (? (BLOCK (ALT (= x ID))))
|
||||
"x=ID*" -> (* (BLOCK (ALT (= x ID))))
|
||||
"x=b" -> (= x b)
|
||||
"x=(A|B)" -> (= x (BLOCK (ALT A) (ALT B)))
|
||||
"x=~(A|B)" -> (= x (~ (BLOCK (ALT A) (ALT B))))
|
||||
"x+=~(A|B)" -> (+= x (~ (BLOCK (ALT A) (ALT B))))
|
||||
"x+=~(A|B)+"-> (+ (BLOCK (ALT (+= x (~ (BLOCK (ALT A) (ALT B)))))))
|
||||
"x=b+" -> (+ (BLOCK (ALT (= x b))))
|
||||
"x+=ID*" -> (* (BLOCK (ALT (+= x ID))))
|
||||
"x+='int'*" -> (* (BLOCK (ALT (+= x 'int'))))
|
||||
"x+=b+" -> (+ (BLOCK (ALT (+= x b))))
|
||||
"('*'^)*" -> (* (BLOCK (ALT (^ '*'))))
|
||||
"({blort} 'x')*" -> (* (BLOCK (ALT {blort} 'x')))
|
||||
"A!" -> (! A)
|
||||
"A^" -> (^ A)
|
||||
"x=A^" -> (= x (^ A))
|
Loading…
Reference in New Issue