ANTLR 解析器为 "true and or false" 语句抛出异常
ANTLR parser to throw exception for "true and or false" statement
我使用的是 ANTLR 4,语法相当复杂。我试图在这里简化...
给定如下表达式:true and or false
我想要一个解析错误,因为定义的操作数在两边都期望表达式,并且它有一个 expr 操作数操作数 expr
我的简化语法是:
grammar MappingExpression;
/* The start rule; begin parsing here.
operator precedence is implied by the ordering in this list */
// =======================
// = PARSER RULES
// =======================
expr:
| op=(TRUE|FALSE) # boolean
| expr op=AND expr # logand
| expr op=OR expr # logor
;
TRUE : 'true';
FALSE : 'false';
WS : [ \t\r\n]+ -> skip; // ignore whitespace
AND : 'and';
OR : 'or';
然而,似乎解析器在评估 true 后停止,即使它识别了所有四个标记(例如,返回的 alt state 在解析器中变为 2)。
如果我无法获得解析异常(因为它看到我认为操作数是表达式),如果我获得了整个解析树,我可以连续抛出两个操作数的运行时异常(例如,'and' 和 'or').
最初,我只有:
expr 'and' expr #logand
expr 'or' expr #logor
这遇到了同样的解析问题(提前停止)。
如果您通过使用内置 EOF
parse
: expr EOF
;
这是我在解析输入时得到的 true and or false
:
查看左下角错误:
line 1:9 extraneous input 'or' expecting {'true', 'false'}
line 1:17 missing {'true', 'false'} at '<EOF>'
Bart Kiers 上面的回答是正确的。我只是想为遇到解析不完整问题的 Java 工作人员提供更多详细信息。
我有一个相当复杂的 g4 文件,它将 expr 定义为一系列与标签关联的 OR'ed 规则(例如,在 # 之后成为 ExpressionsVisitor 中的方法名称)。虽然这似乎有效,但在某些情况下我预计会出现解析错误但收到 none。我也遇到过这样的情况,即只有解析器输入的一部分被解释,因此无法处理整个输入语句。
我修复g4文件如下(完整版为here):
// =======================
// = PARSER RULES
// =======================
expr_to_eof : expr EOF ;
expr:
ID # id
| '*' # field_values
| DESCEND # descendant
| DOLLAR # context_ref
| ROOT # root_path
| ARR_OPEN exprOrSeqList? ARR_CLOSE # array_constructor
| OBJ_OPEN fieldList? OBJ_CLOSE # object_constructor
| expr '.' expr # path
| expr ARR_OPEN ARR_CLOSE # to_array
| expr ARR_OPEN expr ARR_CLOSE # array
| expr OBJ_OPEN fieldList? OBJ_CLOSE # object
| VAR_ID (emptyValues | exprValues) # function_call
| FUNCTIONID varList '{' exprList? '}' # function_decl
| VAR_ID ASSIGN (expr | (FUNCTIONID varList '{' exprList? '}')) # var_assign
| (FUNCTIONID varList '{' exprList? '}') exprValues # function_exec
| op=(TRUE|FALSE) # boolean
| op='-' expr # unary_op
| expr op=('*'|'/'|'%') expr # muldiv_op
| expr op=('+'|'-') expr # addsub_op
| expr op='&' expr # concat_op
| expr op=('<'|'<='|'>'|'>='|'!='|'=') expr # comp_op
| expr 'in' expr # membership
| expr 'and' expr #logand
| expr 'or' expr # logor
| expr '?' expr (':' expr)? # conditional
| expr CHAIN expr # fct_chain
| '(' (expr (';' (expr)?)*)? ')' # parens
| VAR_ID # var_recall
| NUMBER # number
| STRING # string
| 'null' # null
;
根据 Bart 的建议,我为 expr_to_eof 添加了最高规则,导致该方法被添加到 MappingExpressionParser。因此,在我的表达式 class 中,在我调用 tree = parser.expr();
之前,我现在需要调用 tree = parser.expr_to_eof();
,这导致了一个包含 Token.EOF 的最后一个子节点的 ParseTree。 =16=]
因为我的代码需要检查执行的第一步和最后一步的一些条件,所以我最容易添加以下内容以删除 <EOF>
并取回 ParseTree(ExprContext 而不是 Expr_to_eofContext) 我一直在使用添加这条语句:
newTree = ((Expr_to_eofContext)tree).expr();
因此,总的来说,只需在 .g4 文件中添加新规则并更改解析器以便解析到结尾,就可以很容易地修复一个长期存在的错误(以及我推迟解决的其他错误) file() 然后提取整个被解析的表达式。
我希望这将使我能够向 JSONata4Java 添加更多的功能以匹配 JavaScript 版本 jsonata.js
再次感谢巴特!
我使用的是 ANTLR 4,语法相当复杂。我试图在这里简化...
给定如下表达式:true and or false
我想要一个解析错误,因为定义的操作数在两边都期望表达式,并且它有一个 expr 操作数操作数 expr
我的简化语法是:
grammar MappingExpression;
/* The start rule; begin parsing here.
operator precedence is implied by the ordering in this list */
// =======================
// = PARSER RULES
// =======================
expr:
| op=(TRUE|FALSE) # boolean
| expr op=AND expr # logand
| expr op=OR expr # logor
;
TRUE : 'true';
FALSE : 'false';
WS : [ \t\r\n]+ -> skip; // ignore whitespace
AND : 'and';
OR : 'or';
然而,似乎解析器在评估 true 后停止,即使它识别了所有四个标记(例如,返回的 alt state 在解析器中变为 2)。
如果我无法获得解析异常(因为它看到我认为操作数是表达式),如果我获得了整个解析树,我可以连续抛出两个操作数的运行时异常(例如,'and' 和 'or').
最初,我只有:
expr 'and' expr #logand
expr 'or' expr #logor
这遇到了同样的解析问题(提前停止)。
如果您通过使用内置 EOF
parse
: expr EOF
;
这是我在解析输入时得到的 true and or false
:
查看左下角错误:
line 1:9 extraneous input 'or' expecting {'true', 'false'}
line 1:17 missing {'true', 'false'} at '<EOF>'
Bart Kiers 上面的回答是正确的。我只是想为遇到解析不完整问题的 Java 工作人员提供更多详细信息。
我有一个相当复杂的 g4 文件,它将 expr 定义为一系列与标签关联的 OR'ed 规则(例如,在 # 之后成为 ExpressionsVisitor 中的方法名称)。虽然这似乎有效,但在某些情况下我预计会出现解析错误但收到 none。我也遇到过这样的情况,即只有解析器输入的一部分被解释,因此无法处理整个输入语句。
我修复g4文件如下(完整版为here):
// =======================
// = PARSER RULES
// =======================
expr_to_eof : expr EOF ;
expr:
ID # id
| '*' # field_values
| DESCEND # descendant
| DOLLAR # context_ref
| ROOT # root_path
| ARR_OPEN exprOrSeqList? ARR_CLOSE # array_constructor
| OBJ_OPEN fieldList? OBJ_CLOSE # object_constructor
| expr '.' expr # path
| expr ARR_OPEN ARR_CLOSE # to_array
| expr ARR_OPEN expr ARR_CLOSE # array
| expr OBJ_OPEN fieldList? OBJ_CLOSE # object
| VAR_ID (emptyValues | exprValues) # function_call
| FUNCTIONID varList '{' exprList? '}' # function_decl
| VAR_ID ASSIGN (expr | (FUNCTIONID varList '{' exprList? '}')) # var_assign
| (FUNCTIONID varList '{' exprList? '}') exprValues # function_exec
| op=(TRUE|FALSE) # boolean
| op='-' expr # unary_op
| expr op=('*'|'/'|'%') expr # muldiv_op
| expr op=('+'|'-') expr # addsub_op
| expr op='&' expr # concat_op
| expr op=('<'|'<='|'>'|'>='|'!='|'=') expr # comp_op
| expr 'in' expr # membership
| expr 'and' expr #logand
| expr 'or' expr # logor
| expr '?' expr (':' expr)? # conditional
| expr CHAIN expr # fct_chain
| '(' (expr (';' (expr)?)*)? ')' # parens
| VAR_ID # var_recall
| NUMBER # number
| STRING # string
| 'null' # null
;
根据 Bart 的建议,我为 expr_to_eof 添加了最高规则,导致该方法被添加到 MappingExpressionParser。因此,在我的表达式 class 中,在我调用 tree = parser.expr();
之前,我现在需要调用 tree = parser.expr_to_eof();
,这导致了一个包含 Token.EOF 的最后一个子节点的 ParseTree。 =16=]
因为我的代码需要检查执行的第一步和最后一步的一些条件,所以我最容易添加以下内容以删除 <EOF>
并取回 ParseTree(ExprContext 而不是 Expr_to_eofContext) 我一直在使用添加这条语句:
newTree = ((Expr_to_eofContext)tree).expr();
因此,总的来说,只需在 .g4 文件中添加新规则并更改解析器以便解析到结尾,就可以很容易地修复一个长期存在的错误(以及我推迟解决的其他错误) file() 然后提取整个被解析的表达式。
我希望这将使我能够向 JSONata4Java 添加更多的功能以匹配 JavaScript 版本 jsonata.js
再次感谢巴特!