简单的antlr模板重写

简单的antlr模板重写,antlr,language-translation,Antlr,Language Translation,我对antlr完全陌生。我正在尝试使用antlr做一些语言翻译。我想我使用了正确的语法,但我有一个例外 以下是语法的一部分: primary : parExpression | 'this' ('.' Identifier)* identifierSuffix? | 'super' superSuffix | literal | 'new' creator | Identifier ('.' Identifier)* identifierSuffix? | primi

我对antlr完全陌生。我正在尝试使用antlr做一些语言翻译。我想我使用了正确的语法,但我有一个例外

以下是语法的一部分:

primary
:   parExpression
|   'this' ('.' Identifier)* identifierSuffix?
|   'super' superSuffix
|   literal
|   'new' creator
|   Identifier ('.' Identifier)* identifierSuffix?
|   primitiveType ('[' ']')* '.' 'class'
|   'void' '.' 'class'
;
例如,我添加了一个重写规则

|   'new' creator -> 'mynew' creator
例外情况如下:

[11:11:48] error(100): rjava_new_rewrite.g:851:26: syntax error: antlr: NoViableAltException(58@[921:1: rewrite_alternative options {k=1; } : ({...}? => rewrite_template | {...}? => ( rewrite_element )+ -> {!stream_rewrite_element.hasNext()}? ^( ALT[LT(1),"ALT"] EPSILON["epsilon"] EOA["<end-of-alt>"] ) -> ^( ALT[LT(1),"ALT"] ( rewrite_element )+ EOA["<end-of-alt>"] ) | -> ^( ALT[LT(1),"ALT"] EPSILON["epsilon"] EOA["<end-of-alt>"] ) | {...}? ETC );])
[11:11:48] error(100): rjava_new_rewrite.g:851:34: syntax error: antlr: MissingTokenException(inserted [@-1,0:0='<missing SEMI>',<52>,851:33] at creator)
[11:11:48] error(100): rjava_new_rewrite.g:852:5: syntax error: antlr: MissingTokenException(inserted [@-1,0:0='<missing COLON>',<54>,852:4] at |)
[11:11:48] error(100): rjava_new_rewrite.g:0:1: syntax error: assign.types: MismatchedTreeNodeException(0!=3)
[11:11:48] error(100): rjava_new_rewrite.g:0:1: syntax error: assign.types: MismatchedTreeNodeException(3!=28)
[11:11:48] error(100): rjava_new_rewrite.g:0:1: syntax error: assign.types: MismatchedTreeNodeException(3!=27)
[11:11:48] java.util.NoSuchElementException: can't look backwards more than one token in this stream
    at org.antlr.runtime.misc.LookaheadStream.LB(LookaheadStream.java:159)
    at org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:120)
    at org.antlr.runtime.RecognitionException.extractInformationFromTreeNodeStream(RecognitionException.java:144)
    at org.antlr.runtime.RecognitionException.<init>(RecognitionException.java:111)
    at org.antlr.runtime.MismatchedTreeNodeException.<init>(MismatchedTreeNodeException.java:42)
    at org.antlr.runtime.tree.TreeParser.recoverFromMismatchedToken(TreeParser.java:135)
    at org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
    at org.antlr.grammar.v3.AssignTokenTypesWalker.grammar_(AssignTokenTypesWalker.java:388)
    at org.antlr.tool.CompositeGrammar.assignTokenTypes(CompositeGrammar.java:337)
    at org.antlr.tool.Grammar.setGrammarContent(Grammar.java:605)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createNewGrammar(ANTLRGrammarEngineImpl.java:192)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createParserGrammar(ANTLRGrammarEngineImpl.java:225)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createCombinedGrammar(ANTLRGrammarEngineImpl.java:203)
    at org.antlr.works.grammar.antlr.ANTLRGrammarEngineImpl.createGrammars(ANTLRGrammarEngineImpl.java:165)
    at org.antlr.works.grammar.engine.GrammarEngineImpl.getGrammarLanguage(GrammarEngineImpl.java:115)
    at org.antlr.works.components.GrammarWindowMenu.getEditTestRigTitle(GrammarWindowMenu.java:244)
    at org.antlr.works.components.GrammarWindowMenu.menuItemState(GrammarWindowMenu.java:529)
    at org.antlr.works.components.GrammarWindow.menuItemState(GrammarWindow.java:440)
    at org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshMenuItemState(XJMainMenuBar.java:175)
    at org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshMenuState(XJMainMenuBar.java:169)
    at org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshState(XJMainMenuBar.java:153)
    at org.antlr.xjlib.appkit.menu.XJMainMenuBar.refresh(XJMainMenuBar.java:145)
    at org.antlr.works.grammar.decisiondfa.DecisionDFAEngine.refreshMenu(DecisionDFAEngine.java:203)
    at org.antlr.works.components.GrammarWindow.afterParseOperations(GrammarWindow.java:1179)
    at org.antlr.works.components.GrammarWindow.access$200(GrammarWindow.java:96)
    at org.antlr.works.components.GrammarWindow$AfterParseOperations.threadRun(GrammarWindow.java:1553)
    at org.antlr.works.ate.syntax.misc.ATEThread.run(ATEThread.java:152)
    at java.lang.Thread.run(Thread.java:680)
[11:11:48]错误(100):rjava_new_rewrite.g:851:26:语法错误:antlr:noviablealException(58@[921:1:rewrite_可选选项{k=1;}:({…}=>rewrite_模板{…}=>(rewrite|元素)+->{!stream u rewrite____元素.hasNext()}^(ALT[LT(1),“ALT”]EPSILON[“EPSILON”]EOA[“ALT”],“ALT(ALT)]-“重写元素)”](ALT[LT(1),“ALT”]EPSILON[“EPSILON”]EOA[“”])|{…}等);)
[11:11:48]错误(100):rjava_new_rewrite.g:851:34:语法错误:antlr:MissingTokenException(在creator处插入[@-1,0:0=”,851:33]
[11:11:48]错误(100):rjava_new_rewrite.g:852:5:语法错误:antlr:MissingTokenException(插入[@-1,0:0=”,852:4])
[11:11:48]错误(100):rjava_new_rewrite.g:0:1:语法错误:assign.types:MismatchedTreeNodeException(0!=3)
[11:11:48]错误(100):rjava_new_rewrite.g:0:1:语法错误:assign.types:MismatchedTreeNodeException(3!=28)
[11:11:48]错误(100):rjava_new_rewrite.g:0:1:语法错误:assign.types:MismatchedTreeNodeException(3!=27)
[11:11:48]java.util.NoSuchElementException:在此流中不能向后查看多个令牌
位于org.antlr.runtime.misc.LookaheadStream.LB(LookaheadStream.java:159)
位于org.antlr.runtime.misc.LookaheadStream.LT(LookaheadStream.java:120)
在org.antlr.runtime.RecognitionException.extractInformationFromTreeNodeStream(RecognitionException.java:144)上
位于org.antlr.runtime.RecognitionException。(RecognitionException.java:111)
在org.antlr.runtime.MismatchedTreeNodeException.(MismatchedTreeNodeException.java:42)
位于org.antlr.runtime.tree.TreeParser.recoverfrommaschedtoken(TreeParser.java:135)
位于org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115)
位于org.antlr.grammar.v3.AssignTokenTypesWalker.grammar_389;(AssignTokenTypesWalker.java:388)
位于org.antlr.tool.CompositeGrammar.assignTokenTypes(CompositeGrammar.java:337)
位于org.antlr.tool.Grammar.setGrammarContent(Grammar.java:605)
在org.antlr.works.grammar.antlr.antlrgramarengineimpl.createNewGrammar(antlrgramarengineimpl.java:192)上
在org.antlr.works.grammar.antlr.antlrgramarengineimpl.createParserGrammar(antlrgramarengineimpl.java:225)上
位于org.antlr.works.grammar.antlr.antlrgramarengineimpl.createCombinedGrammar(antlrgramarengineimpl.java:203)
位于org.antlr.works.grammar.antlr.antlgrammarenginimpl.createGrammars(antlgrammarenginimpl.java:165)
位于org.antlr.works.grammar.engine.GrammarEngineImpl.getGrammarLanguage(GrammarEngineImpl.java:115)
位于org.antlr.works.components.GrammarWindowMenu.getEditTestRigTitle(GrammarWindowMenu.java:244)
位于org.antlr.works.components.GrammarWindowMenu.menuItemState(GrammarWindowMenu.java:529)
位于org.antlr.works.components.GrammarWindow.menuItemState(GrammarWindow.java:440)
位于org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshMenuItemState(XJMainMenuBar.java:175)
位于org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshMenuState(XJMainMenuBar.java:169)
位于org.antlr.xjlib.appkit.menu.XJMainMenuBar.refreshState(XJMainMenuBar.java:153)
位于org.antlr.xjlib.appkit.menu.XJMainMenuBar.refresh(XJMainMenuBar.java:145)
位于org.antlr.works.grammar.decisiondfa.DecisionDFAEngine.refreshMenu(DecisionDFAEngine.java:203)
位于org.antlr.works.components.GrammarWindow.afterParseOperations(GrammarWindow.java:1179)
访问org.antlr.works.components.GrammarWindow.access$200(GrammarWindow.java:96)
位于org.antlr.works.components.GrammarWindow$AfterParseOperations.threadRun(GrammarWindow.java:1553)
位于org.antlr.works.ate.syntax.misc.ATEThread.run(ATEThread.java:152)
运行(Thread.java:680)
有人能告诉我一些想法吗

秦淳写道:

我想我使用了正确的语法,但我有一个例外

你想错了

不能将语法分析器不匹配的内容放入重写规则中。因此,在你的情况下:

|   'new' creator -> 'mynew' creator
'mynew'
是错误的,因为解析器从未遇到过这样的令牌/规则。如果要在AST中插入解析器没有遇到的标记(在ANTLR中称为虚拟标记),则需要在语法的
tokens{…}
中定义它们,如下所示:

grammar YourGrammarName;

options {
  output=AST;
}

tokens {
  MYNEW;
}

primary
:   ...
|   'new' creator -> ^(MYNEW creator)
|   ...
;
primary
:   ...
|   'new' creator -> ^(MYNEW["mynew"] creator)
|   ...
;
这将插入一个类型为
MYNEW
和内部文本
“MYNEW”
的节点。如果要关联节点中的某些自定义文本,请执行以下操作:

grammar YourGrammarName;

options {
  output=AST;
}

tokens {
  MYNEW;
}

primary
:   ...
|   'new' creator -> ^(MYNEW creator)
|   ...
;
primary
:   ...
|   'new' creator -> ^(MYNEW["mynew"] creator)
|   ...
;
从上面可以看到,我创建了一个AST,其中根节点是
MYNEW
。如果我这样做:

|   'new' creator -> MYNEW creator
ANTLR将从该规则返回2个节点。如果这个规则成为另一个(子)树的根,你会遇到麻烦:毕竟,你可以得到一个有两个根的AST!始终努力让重写规则生成单个AST/节点:

rule
 : subrule ';' -> subrule // omit the semi-colon
 ;
或者当需要创建更多节点时,使用单个根节点创建适当的AST:

rule
 : AToken subrule1 subrule2 ';' -> ^(AToken subrule1 subrule2) // AToken is the root
 ;