我的ANTLR语法解析简单的Java文件有什么问题?

时间:2017-10-30 07:03:39

标签: antlr antlr4

ANTL语法:

class Test {

    void run() { }

}

伪Java文件:

line 3:6 mismatched input 'run' expecting METHOD_NAME

大部分内容都匹配,但METHOD_NAME错误地与methodArgs关联。

{{1}}

methodName

1 个答案:

答案 0 :(得分:1)

这是关于令牌歧义的。这些问题在最近几周被问过几次。请点击this answer中的链接,尤其是消除歧义

一旦出现mismatched错误,请将-tokens添加到grun以显示令牌,这有助于找出您认为词法分析者将做什么与实际做什么之间的差异一样。用你的语法:

CLASS_NAME: ALPHA;
METHOD_NAME: ALPHA;

ALPHA匹配的每个输入都是不明确的,如果不明确,ANTLR会选择第一个规则。

$ grun Question compilationUnit -tokens -diagnostics t.text 
[@0,0:4='class',<'class'>,1:0]
[@1,6:9='Test',<CLASS_NAME>,1:6]
[@2,11:11='{',<'{'>,1:11]
[@3,18:21='void',<CLASS_NAME>,3:4]
[@4,23:25='run',<CLASS_NAME>,3:9]
[@5,26:26='(',<'('>,3:12]
[@6,27:27=')',<')'>,3:13]
[@7,29:29='{',<'{'>,3:15]
[@8,31:31='}',<'}'>,3:17]
[@9,34:34='}',<'}'>,5:0]
[@10,36:35='<EOF>',<EOF>,6:0]
Question last update 0841
line 3:9 mismatched input 'run' expecting METHOD_NAME

因为run已被解释为CLASS_NAME

我会像这样编写语法:

grammar Question;

// Parser

compilationUnit
@init {System.out.println("Question last update 0919");}
    : classDeclaration;

classDeclaration : 'class' ID classBlock
  ;

classBlock: OPEN_BLOCK method* CLOSE_BLOCK
  ;

method: methodReturnValue=ID methodName=ID methodArgs methodBlock
        {System.out.println("Method found : " + $methodName.text + 
                            " which returns a " + $methodReturnValue.text);}
  ;

methodArgs: OPEN_PAREN CLOSE_PAREN
  ;

methodBlock: OPEN_BLOCK CLOSE_BLOCK
  ;

// Lexer

ID : ALPHA ( ALPHA | DIGIT | '_' )* ;

WS: [ \t\n] -> skip;

OPEN_BLOCK: '{';
CLOSE_BLOCK: '}';

OPEN_PAREN: '(';
CLOSE_PAREN: ')';

fragment ALPHA : [a-zA-Z] ;
fragment DIGIT : [0-9] ;

执行:

$ grun Question compilationUnit -tokens -diagnostics t.text 
[@0,0:4='class',<'class'>,1:0]
[@1,6:9='Test',<ID>,1:6]
[@2,11:11='{',<'{'>,1:11]
[@3,18:21='void',<ID>,3:4]
[@4,23:25='run',<ID>,3:9]
[@5,26:26='(',<'('>,3:12]
[@6,27:27=')',<')'>,3:13]
[@7,29:29='{',<'{'>,3:15]
[@8,31:31='}',<'}'>,3:17]
[@9,34:34='}',<'}'>,5:0]
[@10,36:35='<EOF>',<EOF>,6:0]
Question last update 0919
Method found : run which returns a void

$ grun Question compilationUnit -gui t.textenter image description here

来自methodReturnValue规则上下文的侦听器中提供了

methodNamectx