From c607e66f1af435dd54cc2967c0795212a0835a12 Mon Sep 17 00:00:00 2001 From: parrt Date: Wed, 22 Jun 2011 15:03:47 -0800 Subject: [PATCH] added demo target X.stg [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8729] --- .../Java/src/org/antlr/v4/runtime/Lexer.java | 2 +- .../antlr/v4/tool/templates/codegen/X/X.stg | 470 ++++++++++++++++++ tool/src/org/antlr/v4/Tool.java | 2 +- .../org/antlr/v4/codegen/CodeGenerator.java | 15 +- tool/src/org/antlr/v4/tool/ErrorManager.java | 5 + .../org/antlr/v4/test/TestASTStructure.gunit | 217 ++++++++ 6 files changed, 702 insertions(+), 9 deletions(-) create mode 100644 tool/resources/org/antlr/v4/tool/templates/codegen/X/X.stg create mode 100644 tool/test/org/antlr/v4/test/TestASTStructure.gunit diff --git a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java index 829dd7c3c..117080351 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java @@ -77,7 +77,7 @@ public abstract class Lexer extends Recognizer /** The token type for the current token */ public int type; - public QStack modeStack; + public QStack modeStack; // TODO: List? public int mode = Lexer.DEFAULT_MODE; /** You can set the text for the current token to override what is in diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/X/X.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/X/X.stg new file mode 100644 index 000000000..ee249d446 --- /dev/null +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/X/X.stg @@ -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 , + +ParserFile(file, parser, namedActions) ::= << +// $ANTLR ANTLRVersion> generatedTimestamp> + +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, scopes, funcs, atn, actions, sempreds) ::= << +public class extends Parser { + public static final int + =}; separator=", ", wrap, anchor>; + public static final String[] tokenNames = { + "\", "\", "\", + "}; separator=", ", wrap, anchor> + }; + public static final String[] ruleNames = { + "\", + "}; separator=", ", wrap, anchor> + }; + + + + + + @Override + public String[] getTokenNames() { return tokenNames; } + @Override + public String[] getRuleNames() { return ruleNames; } + @Override + public ATN getATN() { return _ATN; } + + + +} +>> + +dumpActions(actions,sempreds) ::= << + + public boolean sempred(int ruleIndex, int predIndex) { + switch ( predIndex ) { + : return ;}; separator="\n"> + } + return true; + } + + + public void action(int ruleIndex, int actionIndex) { + switch ( actionIndex ) { + : break;}; separator="\n"> + } + } + +>> + +ctor(p) ::= << +public (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) ::= << + + + + }>public final () throws RecognitionException { + _ctx = new ParserRuleContext(_ctx, ); + ParserRuleContext _thisctx = _ctx; + + _stack.push(new ()); + + //System.out.println("enter "+ruleNames[]); + _stack.push(new ());}; separator="\n"> + + + try { + + } + catch (RecognitionException re) { + reportError(re); + recover(); + } + finally { + + _stack.pop();}; separator="\n"> + _stack.pop(); + + _ctx = (ParserRuleContext)_ctx.parent; + //System.out.println("exit "+ruleNames[]); + } + return _thisctx; +} +>> + +CodeBlock(c, ops) ::= << + +>> + +LL1AltBlock(choice, alts, error) ::= << +switch ( input.LA(1) ) { + + + break;}; separator="\n"> + default : + +} +>> + +LL1OptionalBlock(choice, alts, error) ::= << +switch ( input.LA(1) ) { + + + break;}; separator="\n"> + default : + +} +>> + +LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= << + +if ( ) { + +} +) ) !> +>> + +LL1StarBlock(choice, alts, sync) ::= << +: +while (true) { + switch ( input.LA(1) ) { + + + break;}; separator="\n"> + + break ; + } + // +} +>> + +LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration, sync) ::= << + +while ( ) { + + + // +} +>> + +LL1PlusBlock(choice, alts, iteration, loopExpr, sync, error, iterationSync) ::= << +// +do { + switch ( input.LA(1) ) { + + + break;}; separator="\n"> + default : + + } + + // +} while ( ); +>> + +LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration, + sync, iterationSync) ::= +<< +// + +do { + + +// +} while ( ); +>> + +// LL(*) stuff + +AltBlock(choice, alts, error) ::= << +switch ( _interp.adaptivePredict(input,,_ctx) ) { + : + + break;}; separator="\n"> + default : + +} +>> + +OptionalBlock(choice, alts, error) ::= << +switch ( _interp.adaptivePredict(input,,_ctx) ) { + : + + break;}; separator="\n"> +} +>> + +StarBlock(choice, alts, sync) ::= << +int _alt = _interp.adaptivePredict(input,,_ctx); +while ( _alt!= ) { + switch ( _alt ) { + : + + break;}; separator="\n"> + } + _alt = _interp.adaptivePredict(input,,_ctx); +} +>> + +PlusBlock(choice, alts, error) ::= << +int _alt = _interp.adaptivePredict(input,,_ctx); +do { + switch ( _alt ) { + : + + break;}; separator="\n"> + default : + + } + _alt = _interp.adaptivePredict(input,,_ctx); +} while ( _alt!= ); +>> + +Sync(s) ::= "sync();" + +ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this,_ctx);" + +TestSetInline(s) ::= << +==}; separator=" || "> +>> + +cases(ttypes) ::= << +:}; separator="\n"> +>> + +InvokeRule(r) ::= << +_ctx.s = ; + = }>(}>); +>> + +MatchToken(m) ::= << +_ctx.s = ; + = }>(Token)match(); +>> + +// ACTION STUFF + +Action(a, chunks) ::= "" + +ForcedAction(a, chunks) ::= "" + +SemPred(p, chunks) ::= << +if (!()) throw new FailedPredicateException(this, input, "", """!>); +>> + +ActionText(t) ::= "" +ArgRef(a) ::= "_ctx." +RetValueRef(a) ::= "_ctx." +QRetValueRef(a) ::= "." +/** How to translate $tokenLabel */ +TokenRef(t) ::= "" +SetAttr(s,rhsChunks) ::= "_ctx. = ;" +//SetQAttr(s,rhsChunks) ::= ". = ;" + +TokenPropertyRef_text(t) ::= "(!=null?.getText():null)" +TokenPropertyRef_type(t) ::= "(!=null?.getType():0)" +TokenPropertyRef_line(t) ::= "(!=null?.getLine():0)" +TokenPropertyRef_pos(t) ::= "(!=null?.getCharPositionInLine():0)" +TokenPropertyRef_channel(t) ::= "(!=null?.getChannel():0)" +TokenPropertyRef_index(t) ::= "(!=null?.getTokenIndex():0)" +TokenPropertyRef_tree(t) ::= "_tree" +TokenPropertyRef_int(t) ::= "(!=null?Integer.valueOf(.getText()):0)" + +RulePropertyRef_start(r) ::= "(!=null?(().start):null)" +RulePropertyRef_stop(r) ::= "(!=null?(().stop):null)" +RulePropertyRef_tree(r) ::= "(!=null?(().tree):null)" +RulePropertyRef_text(r) ::= "(!=null?((TokenStream)input).toString(.start,.stop):null)" +RulePropertyRef_st(r) ::= "(!=null?.st:null)" + +DynScopeRef(s) ::= "_stack" +DynScopeAttrRef(s) ::= "_stack.peek()." +DynScopeAttrRef_negIndex(s, indexChunks) ::= + "_stack.get(_stack.size()--1)." +DynScopeAttrRef_index(s, indexChunks) ::= + "_stack.get()." +SetDynScopeAttr(s, rhsChunks) ::= + "_stack.peek(). =;" +SetDynScopeAttr_negIndex(s, indexChunks, rhsChunks) ::= + "_stack.get(_stack.size()--1). =;" +SetDynScopeAttr_index(s, indexChunks, rhsChunks) ::= + "_stack.get(). =;" + +AddToList(a) ::= ".add();" + +TokenDecl(t) ::= "Token ;" +TokenTypeDecl(t) ::= "int ;" +TokenListDecl(t) ::= "List\ = new ArrayList\();" +RuleContextDecl(r) ::= " ;" + +CaptureNextToken(d) ::= " = input.LT(1);" +CaptureNextTokenType(d) ::= " = input.LA(1);" + +StructDecl(s,attrs) ::= << +public static class extends ParserRuleContext { + ;}; separator="\n"> + + public (,}> LABitSet follow) { + super(follow); + = ;}; separator="\n"> + } + +}; +>> + +DynamicScopeStruct(d,attrs) ::= << +public static class { + ;}; separator="\n"> +}; +public QStack\<\> _stack = new QStack\<\>(); +>> + +AttributeDecl(d) ::= "" + +DFADecl(dfa) ::= << +// define +>> + +BitSetDecl(b) ::= << +public static final LABitSet =new LABitSet(new long[]{L};separator=",">}, true); +>> + +LexerFile(lexerFile, lexer, namedActions) ::= << +// $ANTLR ANTLRVersion> generatedTimestamp> + +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, atn, actions, sempreds) ::= << +public class extends Lexer { + public static final int + =}; separator=", ", wrap, anchor>; + = ;}; separator="\n"> + + public static final String[] tokenNames = { + "\", "\", "\", + "}; separator=", ", wrap, anchor> + }; + public static final String[] ruleNames = { + "\", + "}; separator=", ", wrap, anchor> + }; + + + + public (CharStream input) { + super(input); + _interp = new LexerInterpreter(this,_ATN); + } + + public String getGrammarFileName() { return ""; } + @Override + public String[] getTokenNames() { return tokenNames; } + @Override + public String[] getRuleNames() { return ruleNames; } + @Override + public ATN getATN() { return _ATN; } + + + + + +} +>> + + +SerializedATN(model) ::= << +public static final String _serializedATN = + ""}, 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 _actions(int action) { + System.out.println("exec action "+action); + switch ( action ) { + : + + break; + }> + } +}<\n> +>> + +sempredMethod(name, ruleIndex, preds) ::= << +public boolean _sempreds(int pred) { + switch ( pred ) { + : + return

; + }> + 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) ::= << + +>> + +codeFileExtension() ::= ".java" + +true() ::= "true" +false() ::= "false" diff --git a/tool/src/org/antlr/v4/Tool.java b/tool/src/org/antlr/v4/Tool.java index 7958d46a8..2653f07f8 100644 --- a/tool/src/org/antlr/v4/Tool.java +++ b/tool/src/org/antlr/v4/Tool.java @@ -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); } diff --git a/tool/src/org/antlr/v4/codegen/CodeGenerator.java b/tool/src/org/antlr/v4/codegen/CodeGenerator.java index a668627f9..e7e779117 100644 --- a/tool/src/org/antlr/v4/codegen/CodeGenerator.java +++ b/tool/src/org/antlr/v4/codegen/CodeGenerator.java @@ -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); } } diff --git a/tool/src/org/antlr/v4/tool/ErrorManager.java b/tool/src/org/antlr/v4/tool/ErrorManager.java index f2971696d..50a34d01e 100644 --- a/tool/src/org/antlr/v4/tool/ErrorManager.java +++ b/tool/src/org/antlr/v4/tool/ErrorManager.java @@ -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, diff --git a/tool/test/org/antlr/v4/test/TestASTStructure.gunit b/tool/test/org/antlr/v4/test/TestASTStructure.gunit new file mode 100644 index 000000000..1afda9871 --- /dev/null +++ b/tool/test/org/antlr/v4/test/TestASTStructure.gunit @@ -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;" -> + (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}) <>" -> + (ALT_REWRITE + (ALT A) + (-> (TEMPLATE (ARGLIST (= a {x}) (= b {y})) <>))) + + "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))