gpt4 book ai didi

parsing - 如何正确解析 VB Case 语句?

转载 作者:行者123 更新时间:2023-12-04 21:34:41 25 4
gpt4 key购买 nike

我正在尝试解析 VBA 代码,规范的 5.4.2.10 部分定义了 Select Case声明,我们定义如下:

// 5.4.2.10 Select Case Statement
selectCaseStmt :
SELECT whiteSpace? CASE whiteSpace? selectExpression endOfStatement
caseClause*
caseElseClause?
END_SELECT
;
selectExpression : expression;
caseClause :
CASE whiteSpace rangeClause (whiteSpace? COMMA whiteSpace? rangeClause)* endOfStatement block
;
caseElseClause : CASE whiteSpace? ELSE endOfStatement block;
rangeClause :
expression
| selectStartValue whiteSpace TO whiteSpace selectEndValue
| (IS whiteSpace?)? comparisonOperator whiteSpace? expression
;
selectStartValue : expression;
selectEndValue : expression;

问题在于 expressionrangeClause优先,并使其:

Select Case foo
Case Is = 42
Exit Sub
End Select


...最终被接走并被视为 {undeclared-variable} {EQ} {literal} ,这是一个问题,因为 Is应该是词法分析器标记,而不是比较表达式的 LHS:
expression whiteSpace? (EQ | NEQ | LT | GT | LEQ | GEQ | LIKE | IS) whiteSpace? expression    # relationalOp

我尝试重新排序替代品,以便 expression分支具有较低的优先级,如下所示:
rangeClause :
selectStartValue whiteSpace TO whiteSpace selectEndValue
| (IS whiteSpace?)? comparisonOperator whiteSpace? expression
| expression
;

但这以各种方式破坏了整个语法(在我的项目中破坏了大约 1000 个测试),因此我尝试更改 rangeClause对此(删除了可选标记,因为 Is 没有 = 实际上是非法的 VBA 代码):
rangeClause :
expression (whiteSpace TO whiteSpace expression)? #caseFromTo
| (IS whiteSpace comparisonOperator whiteSpace)? expression #caseIs
;

然后与 CaseFromToContext 一起工作和 CaseIsContext代码中的类(必须保持编译),但它再次破坏了我项目中的约 1000 个测试。

然后我想,“嘿,这可能是模棱两可的!”并把它变成了这样:
rangeClause :
expression whiteSpace TO whiteSpace expression #caseFromTo
| IS whiteSpace comparisonOperator whiteSpace expression #caseIs
| expression #caseExpr
;

...但没有运气,同样的结果。

我该如何制作 rangeClause理解这个烦人的 Case Is = foobar句法?我正在使用 ANTLR 4.3,但我们计划很快升级到 ANTLR 4.6。

如果需要额外的上下文, the complete VBAParser.g4 grammar is on github .

最佳答案

事实证明,重新排序确实有效,但为了避免解析中的歧义,IS whiteSpace comparisonOperator必须首先出现:

rangeClause :
(IS whiteSpace?)? comparisonOperator whiteSpace? expression
| selectStartValue whiteSpace TO whiteSpace selectEndValue
| expression

问题出在 expression (并且通过扩展 selectStartValueselectEndValue )将递归匹配 Is =因为 comparisonOperator comparisonOperator是表达式匹配。可能有一些工作可以防止 comparisonOperator comparisonOperator来自匹配 expression (它在 VBA AFAIK 中永远无效),但上面的方法是一种快速而肮脏的修复方法。

基本上所有上述语法都是确保“无效” comparisonOperator comparisonOperator匹配为 rangeClause在它可以匹配为 expression 之前.

关于parsing - 如何正确解析 VB Case 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41596846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com