0

私は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)

誰かが何か考えを与えることができますか?

4

1 に答える 1

2

qinsoon さんが書きました:

正しい構文を使用していると思いますが、例外があります。

あなたは間違って考えました。:)

パーサーによって一致しなかったものを書き換えルールに入れることはできません。だからあなたの場合:

|   'new' creator -> 'mynew' creator

'mynew'パーサーがそのようなトークン/ルールに遭遇したことがないため、間違っています。パーサーが遭遇しなかった AST にトークンを挿入したい場合 (ANTLR では架空のトークンと呼ばれます)、次tokens {...}のように文法の でそれらを定義する必要があります。

grammar YourGrammarName;

options {
  output=AST;
}

tokens {
  MYNEW;
}

primary
:   ...
|   'new' creator -> ^(MYNEW creator)
|   ...
;

MYNEWこれにより、 typeと inner-textを持つノードが挿入されます"MYNEW"。ノードにカスタム テキストを関連付ける場合は、次のようにします。

primary
:   ...
|   'new' creator -> ^(MYNEW["mynew"] creator)
|   ...
;

上記からわかるように、ルート ノードが である AST を作成しましたMYNEW。私が行った場合:

|   'new' creator -> MYNEW creator

ANTLR は、そのルールから 2 つのノードを返します。そのルールが別の (サブ) ツリーのルートになると、問題が発生します。結局のところ、2 つのルートを持つ AST を取得できます! 書き換えルールが単一の AST/ノードのいずれかを生成できるように常に努力してください。

rule
 : subrule ';' -> subrule // omit the semi-colon
 ;

または、さらにノードを作成する必要がある場合は、単一のルートノードで適切な AST を作成します。

rule
 : AToken subrule1 subrule2 ';' -> ^(AToken subrule1 subrule2) // AToken is the root
 ;
于 2012-05-22T07:26:52.610 に答える