ANTLR语法错误

标签 antlr grammar antlr3 context-free-grammar

我正在尝试使用 ANTLR 3.4 构建 C 编译器。

此处列出的全套语法,

program         : (vardeclaration | fundeclaration)*                    ;
vardeclaration  : INT ID (OPENSQ NUM CLOSESQ)? SEMICOL  ;

fundeclaration  : typespecifier ID OPENP params CLOSEP compoundstmt     ;
typespecifier   : INT | VOID                                            ;
params          : VOID | paramlist                                      ;
paramlist       : param (COMMA param)*                                  ;
param           :  INT ID (OPENSQ CLOSESQ)?         ;

compoundstmt    : OPENCUR vardeclaration* statement* CLOSECUR           ;
statementlist   : statement*                                            ;

statement       : expressionstmt | compoundstmt | selectionstmt | iterationstmt | returnstmt;
expressionstmt  : (expression)? SEMICOL;
selectionstmt   : IF OPENP expression CLOSEP statement (options {greedy=true;}: ELSE statement)?;
iterationstmt   : WHILE OPENP expression CLOSEP statement;
returnstmt      : RETURN (expression)? SEMICOL;

expression      : (var EQUAL expression) | sampleexpression;
var             : ID ( OPENSQ expression CLOSESQ )? ;

sampleexpression: addexpr ( ( LOREQ | LESS | GRTR | GOREQ | EQUAL | NTEQL) addexpr)?;
addexpr         : mulexpr ( ( PLUS | MINUS ) mulexpr)*;
mulexpr         : factor  ( ( MULTI | DIV  ) factor )*; 

factor          : ( OPENP expression CLOSEP ) | var | call  | NUM;
call            : ID OPENP arglist? CLOSEP;
arglist         : expression ( COMMA expression)*;

使用的词法分析器规则如下,

ELSE    : 'else'    ;
IF      : 'if'      ;
INT     : 'int'     ;
RETURN  : 'return'  ;
VOID    : 'void'    ;
WHILE   : 'while'   ;

PLUS    : '+' ;
MINUS   : '-' ;
MULTI   : '*' ;
DIV     : '/' ;

LESS    : '<'  ;
LOREQ   : '<=' ;
GRTR    : '>'  ;
GOREQ   : '>=' ;

EQUAL   : '==' ;
NTEQL   : '!=' ;
ASSIGN  : '='  ;

SEMICOL : ';' ;
COMMA   : ',' ;

OPENP   : '(' ;
CLOSEP  : ')' ;
OPENSQ  : '[' ;
CLOSESQ : ']' ;
OPENCUR : '{' ;
CLOSECUR: '}' ;

SCOMMENT: '/*' ;
ECOMMENT: '*/' ;


ID  : ('a'..'z' | 'A'..'Z')+/*(' ')*/ ;
NUM : ('0'..'9')+ ;
WS  : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;};
COMMENT: '/*' .* '*/' {$channel = HIDDEN;};

但是我试图保存这个它给我错误,

error(211): /CMinusMinus/src/CMinusMinus/CMinusMinus.g:33:13: [fatal] rule expression has non-LL(*) decision due to recursive rule invocations reachable from alts 1,2.  Resolve by left-factoring or using syntactic predicates or using backtrack=true option.
 |---> expression       : (var EQUAL expression) | sampleexpression;

1 error

我该如何解决这个问题?

最佳答案

如前所述:您的语法规则 expression 不明确:该规则中的两个备选方案都以 var 开头,或者可以是 var

您需要稍微“帮助”您的解析器。如果解析可以看到 var 后跟 EQUAL,它应该选择备选方案 1,否则选择备选方案 2。这可以通过使用句法谓词( (var EQUAL)=> 下面规则的一部分)。

expression
 : (var EQUAL)=> var EQUAL expression
 |               sampleexpression
 ;

此问答中有关谓词的更多信息:What is a 'semantic predicate' in ANTLR?

关于ANTLR语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9545113/

相关文章:

grammar - 我如何构建生成这种语言的语法?

parsing - ANTLR 在词法分析/解析中包含元数据的最佳方式(自定义对象、注释类型)

java - 我如何引用在 ANTLR 中多次调用同一规则?

antlr - 如何使用 Java System.out.println 在解析器中直接生成 XML

swift - ANTLR 中 WS 背后的魔力是什么?

java - 获取 Antlr 规则的原始文本

java Main < inputfile 不起作用(Main 是一个用于测试 ANTLR 语法的 java 类)

javascript - antlr 生成词法分析器但不生成解析器

c - 为什么这些冲突出现在以下 XML 的 yacc 语法中

algorithm - "one or more"带 LL 解析器