Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr 如何获得(A*B)>;这个语法解析的C字符串?_Antlr_Context Free Grammar_Recursive Descent - Fatal编程技术网

Antlr 如何获得(A*B)>;这个语法解析的C字符串?

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

问题在于--addExpression((EQ | NE | GT | LT | LE | GE)addExpression)+--。 通过这样做,我想过滤数学表达式,使其不再单独存在,除非后面跟一个关系表达式,以使其整体上具有逻辑性。。。我不希望我的解析器单独解析数学表达式

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-token
LPAR
标记以rule
compExpr
开头的逻辑表达式或以
primaryExpr
开头的算术表达式的开头。默认情况下,ANTLR无法知道输入是标记逻辑表达式分组的开始(
(3+3==6)
)还是算术/数字表达式分组的开始(
(3+3)==6)
).rule
compExpr
中的语法谓词用于帮助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返回[对象结果]
@初始化{