2012-05-22 3 views
0

Я совершенно не знаком с antlr. Я пытаюсь использовать antlr для перевода языка. Я думаю, что я использую правильный синтаксис, но у меня есть исключение.simple antlr template rewrite

Ниже часть грамматики:

primary 
: parExpression 
| 'this' ('.' Identifier)* identifierSuffix? 
| 'super' superSuffix 
| literal 
| 'new' creator 
| Identifier ('.' Identifier)* identifierSuffix? 
| primitiveType ('[' ']')* '.' 'class' 
| 'void' '.' 'class' 
; 

Я добавил правила перезаписи, например

| 'new' creator -> 'mynew' creator 

Исключение happends:

[11:11:48] error(100): rjava_new_rewrite.g:851:26: syntax error: antlr: NoViableAltException([email protected][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) 

Можно ли дать какие-либо идеи ?

ответ

2

qinsoon писал:

Я думаю, использовать правильный синтаксис, но я получил исключение.

Вы считаете неправильным. :)

Вы не можете поместить вещи в правило перезаписи, которое не было согласовано с парсером. Так что в вашем случае:

| 'new' creator -> 'mynew' creator 

'mynew' неправильно, потому что синтаксический анализатор никогда не сталкивался с таким маркером/правила. Если вы хотите вставить маркеры в вашем AST парсер не сталкиваются (они называются воображаемые маркеры в ANTLR), вам необходимо определить их в tokens {...} вашей грамматики, например:

grammar YourGrammarName; 

options { 
    output=AST; 
} 

tokens { 
    MYNEW; 
} 

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

Это добавит узел с типом MYNEW и innner-text "MYNEW". Если вы хотите, чтобы связать некоторый произвольный текст в узле, сделать это следующим образом:

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 
; 
Смежные вопросы