Antlr 如何获得(A*B)>;这个语法解析的C字符串?
问题在于--addExpression((EQ | NE | GT | LT | LE | GE)addExpression)+--。 通过这样做,我想过滤数学表达式,使其不再单独存在,除非后面跟一个关系表达式,以使其整体上具有逻辑性。。。我不希望我的解析器单独解析数学表达式Antlr 如何获得(A*B)>;这个语法解析的C字符串?,antlr,context-free-grammar,recursive-descent,Antlr,Context Free Grammar,Recursive Descent,问题在于--addExpression((EQ | NE | GT | LT | LE | GE)addExpression)+--。 通过这样做,我想过滤数学表达式,使其不再单独存在,除非后面跟一个关系表达式,以使其整体上具有逻辑性。。。我不希望我的解析器单独解析数学表达式 expression : logicalExpression ; primitive : DECIMAL | UNSIGNED_INTEGER
expression
:
logicalExpression
;
primitive
:
DECIMAL
| UNSIGNED_INTEGER
| SIGNED_INTEGER
| VARIABLE
| '(' logicalExpression ')'
| '{' logicalExpression '}'
| '[' logicalExpression ']'
;
notExpression
:
(NOT)* primitive
;
signExpression
:
( '-' | '+' )* notExpression
;
mulExpression
:
signExpression ( ( '*' | '/' ) signExpression)*
;
addExpression
:
mulExpression ( ( '+' | '-' ) mulExpression)*
;
relationalExpression
:
addExpression ((EQ | NE | GT | LT | LE | GE) addExpression)+
| '(' VARIABLE ')'
| '{' VARIABLE '}'
| '[' VARIABLE ']'
| VARIABLE
;
测试:
Input string: (5) --> Expected: to fail -- Current:failed
Input string: 5*6 --> Expected: to fail -- Current:failed
Input string: A-B --> Expected: to fail -- Current:failed
Input string: A/B --> Expected: to fail -- Current:failed
Input string: 5/A --> Expected: to fail -- Current:failed
Input string: --2 --> Expected: to fail -- Current:failed
Input string: 5++ --> Expected: to fail -- Current:failed
Input string: A-B and B-A --> Expected: to fail -- Current:failed
Input string: (A and B)--> Expected: to pass {AND(A,B)} -- Current:failed
Input string: A and B--> Expected: to pass AND(A,B) -- Current:failed
Input string: (5)>6 --> Expected: to pass {GT(5,6)} -- Current:failed
Input string: 5>6 --> Expected: to pass {GT(5,6)} -- Current:pass
Input string: 5*6 < 6-5 --> Expected: to pass GT(MUL(5,6),SUB(5,6)) --Current:pass
Input string: A/B == B/A --> Expected: to pass -- Current:pass
Input string: (A/B)=B/A --> Expected: to pass -- Current:failed
Input string: 5 /= 5 --> Expected: to pass -- Current:pass
输入字符串:(5)-->预期:失败--当前:失败
输入字符串:5*6-->预期:失败--当前:失败
输入字符串:A-B-->预期:失败--当前:失败
输入字符串:A/B-->预期:失败--当前:失败
输入字符串:5/A-->预期:失败--当前:失败
输入字符串--2-->预期:失败--当前:失败
输入字符串:5++-->预期:失败--当前:失败
输入字符串:A-B和B-A-->预期:失败--当前:失败
输入字符串:(A和B)-->应为:通过{和(A,B)}--当前:失败
输入字符串:A和B-->预期:通过和(A,B)--当前:失败
输入字符串:(5)>6-->预期:通过{GT(5,6)}--当前:失败
输入字符串:5>6-->预期:通过{GT(5,6)}--当前:通过
输入字符串:5*6<6-5-->预期:通过GT(MUL(5,6),SUB(5,6))--当前:通过
输入字符串:A/B==B/A-->预期:通过--当前:通过
输入字符串:(A/B)=B/A-->预期:通过--当前:失败
输入字符串:5/=5-->预期:通过--当前:通过
下面是两个简单的ANTLR语法,它们演示了两种方法来计算逻辑和算术表达式的混合,然后是测试类及其输出。第一个语法采用您请求的格式,使用ANTLR确定表达式类型并确保表达式值兼容。另一种形式使用语法中的动作确定表达式类型。我在这里提供它以供比较
我在这两种语法中都硬编码了表达式求值,以使示例更有用,并表明它们按预期工作。请注意,除了下面的测试代码之外,我还没有测试这些语法。此外,我只包含了演示感兴趣的概念所需的运算符。添加其他内容应该很容易
要求ANTLR保持表达式类型不同需要告诉ANTLR当运算符对多个表达式类型有效时该怎么做。例如,在下面的语法
logicalrules
中,lexer-tokenLPAR
标记以rulecompExpr
开头的逻辑表达式或以primaryExpr
开头的算术表达式的开头。默认情况下,ANTLR无法知道输入是标记逻辑表达式分组的开始((3+3==6)
)还是算术/数字表达式分组的开始((3+3)==6)
).rulecompExpr
中的语法谓词用于帮助ANTLR区分这两种选择,实际上是告诉它等待观望
g-让ANTLR规则区分布尔表达式和数值表达式
语法逻辑规则;
语句返回[布尔结果]
:logicalExpr{$result=$logicalExpr.result;}EOF
;
logicalExpr返回[布尔结果]
@init{$result=true;}
:lhs=compExpr{$result=$lhs.result;}
(和rhs=compExpr
{$result=$result&&$rhs.result;}
)*
;
compExpr返回[布尔结果]
@init{$result=true;}
:(eqExpr)=>eqExpr{$result=$eqExpr.result;}
//^^需要一个语法谓词来区分逻辑分组和算术分组
|LPAR logicalExpr{$result=$logicalExpr.result;}RPAR
//^^仅在此级别对逻辑表达式进行分组。
;
eqExpr返回[布尔结果]
@init{$result=true;}
:lhs=算术表达式
(等式rhs=算术表达式
{$result=$result&&$lhs.result==$rhs.result;}
)+
//^^use+:算术表达式的逻辑表达式
//需要逻辑运算来生成布尔值
;
算术表达式返回[int结果]
@init{$result=0;}
:lhs=primaryExpr{$result+=$lhs.result;}
(加上rhs=primaryExpr
{$result+=$rhs.result;}
)*
;
primaryExpr返回[int结果]
@init{$result=0;}
:INT{$result=$INT.INT;}
|LPAR arithmeticExpr RPAR{$result=$arithmeticExpr.result;}
//^^仅将此级别的其他数值/算术表达式分组。
;
INT:('0'..'9')+;
及:"&";
等式:'=';
LPAR:'(';
RPAR:')';
加:“+”;
WS:(“”|’\t’|’\r’|’\n’+{skip();};
使用代码而不是ANTLR规则计算表达式的结果类型会产生如下语法。请注意,分组只在一个级别上进行,不需要语法谓词。语法总体上保持相对简单。与前面的语法一样,此语法在遇到无效类型conv时会产生错误版本 g-让代码区分布尔表达式和数值表达式
语法逻辑评估;
@解析器::成员{
私有静态布尔toBoolean(对象obj){
if(obj instanceof Boolean){
返回(布尔)对象;
}否则{
抛出新的RuntimeException(“无法将“+obj+”转换为布尔值”);
}
}
私有静态int-toInt(对象对象对象){
if(obj instanceof Integer){
返回(整数)obj;
}否则{
抛出新的RuntimeException(“无法将“+obj+”转换为整数”);
}
}
}
语句返回[对象结果]
:expr{$result=$expr.result;}EOF
;
expr返回[对象结果]
:lhs=compExpr{$result=$lhs.result;}
(和rhs=compExpr
{$result=toBoolean($result)&&toBoolean($rhs.result);}
)*
;
compExpr返回[对象结果]
@初始化{