【问题标题】:antlr grammar definitionantlr 语法定义
【发布时间】:2017-10-10 09:30:09
【问题描述】:

我对编译器理论比较陌生,我只是想创建一个语法来解析一些比较,以便以后评估它们。我发现 antlr 是一个指定语法的强大工具。根据我在理论中学到的知识,我知道具有较高优先级的运算符必须比具有较低优先级的运算符在更深的层次上声明。此外,如果我想让某些规则保持关联,我知道我必须将递归设置在规则的左侧。知道我已经创建了一个基本语法来使用 &&、||、!=、==、、=、(,) 和 !

start
 : orExpr
 ;

orExpr
 : orExpr OR andExpr
 | andExpr
 ;

andExpr
 : andExpr AND eqNotEqExpr
 | eqNotEqExpr
 ;

eqNotEqExpr
 : eqNotEqExpr NEQ compExpr
 | eqNotEqExpr EQ compExpr
 | compExpr
 ;

compExpr
 : compExpr LT compExpr
 | compExpr GT compExpr
 | compExpr LTEQ compExpr
 | compExpr GTEQ compExpr
 | notExpr
 ;

notExpr
 : NOT notExpr
 | parExpr
 ;

parExpr
 : OPAR orExpr CPAR
 | id
 ;

id
 : INT
 | FLOAT
 | TRUE
 | FALSE
 | ID
 | STRING
 | NULL
 ;

但是在互联网上搜索我发现了一种不同的方式来指定上述语法,它不遵循我提到的关于运算符优先级和左关联性的上述规则:

start
 : expr
 ;

expr
 : NOT expr                             //notExpr
 | expr op=(LTEQ | GTEQ | LT | GT) expr //relationalExpr
 | expr op=(EQ | NEQ) expr              //equalityExpr
 | expr AND expr                        //andExpr
 | expr OR expr                         //orExpr
 | atom                                 //atomExpr
 ;

atom
 : OPAR expr CPAR //parExpr
 | (INT | FLOAT)  //numberAtom
 | (TRUE | FALSE) //booleanAtom
 | ID             //idAtom
 | STRING         //stringAtom
 | NULL           //nullAtom
 ;

有人可以解释为什么这种定义语法的方式也有效吗?是因为antlr的一些特殊处理还是其他类型的语法定义?

下面是为语法定义的运算符和ID:

OR : '||';
AND : '&&';
EQ : '==';
NEQ : '!=';
GT : '>';
LT : '<';
GTEQ : '>=';
LTEQ : '<=';
NOT : '!';

OPAR : '(';
CPAR : ')';

TRUE : 'true';
FALSE : 'false';
NULL : 'null';

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

INT
 : [0-9]+
 ;

FLOAT
 : [0-9]+ '.' [0-9]* 
 | '.' [0-9]+
 ;

STRING
 : '"' (~["\r\n] | '""')* '"'
 ;

COMMENT
 : '//' ~[\r\n]* -> skip
 ;

SPACE
 : [ \t\r\n] -> skip
 ;

OTHER
 : . 
 ;

【问题讨论】:

    标签: antlr


    【解决方案1】:

    这是 ANTLR v4 特有的。

    在幕后,像这样的规则将被重写为与您在左递归消除步骤中手动完成的相同的内容。 ANTLR 这样做是为了方便,因为 LL 语法不能包含左递归规则,因为将此类规则直接转换为解析器代码会在代码中产生无限递归(无条件调用自身的函数)。

    the docs page about left-recursion 中有更多信息和转换示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多