gpt4 book ai didi

c# - 2 个不同域值中的 ANTLR3 公共(public)值

转载 作者:行者123 更新时间:2023-11-30 22:35:34 26 4
gpt4 key购买 nike

我需要为以下搜索条件定义一个语言解析器:

CRITERIA_1=<values-set-#1> AND/OR CRITERIA_2=<values-set-#2>;

在哪里<values-set-#1>可以具有 1-50 和 <values-set-#2> 之间的值可以来自以下集合 (5, A, B, C) - 此处大小写不重要。

我决定在 C# (CSharp3) 中使用 ANTLR3 (v3.4) 和输出,直到现在它都可以正常工作。问题是当我提供来自两个数据集的值时它无法解析字符串(即在本例中为“5”)。例如,如果我提供以下字符串

CRITERIA_1=5;

它在值节点应该是的位置返回以下错误:

<unexpected: [@1,11:11='5',<27>,1:11], resync=5>

语法定义文件如下:

grammar ZeGrammar;

options {
language=CSharp3;
TokenLabelType=CommonToken;
output=AST;
ASTLabelType=CommonTree;
k=3;
}

tokens
{
ROOT;
CRITERIA_1;
CRITERIA_2;
OR = 'OR';
AND = 'AND';
EOF = ';';
LPAREN = '(';
RPAREN = ')';
}

public
start
: expr EOF -> ^(ROOT expr)
;

expr
: subexpr ((AND|OR)^ subexpr)*
;

subexpr
: grouppedsubexpr
| 'CRITERIA_1=' rangeval1_expr -> ^(CRITERIA_1 rangeval1_expr)
| 'CRITERIA_2=' rangeval2_expr -> ^(CRITERIA_2 rangeval2_expr)
;

grouppedsubexpr
: LPAREN! expr RPAREN!
;

rangeval1_expr
: rangeval1_subexpr
| RANGE1_VALUES
;

rangeval1_subexpr
: LPAREN! rangeval1_expr (OR^ rangeval1_expr)* RPAREN!
;

RANGE1_VALUES
: (('0'..'4')? ('0'..'9') | '5''0')
;

rangeval2_expr
: rangeval2_subexpr
| RANGE2_VALUES
;

rangeval2_subexpr
: LPAREN! rangeval2_expr (OR^ rangeval2_expr)* RPAREN!
;

RANGE2_VALUES
: '5' | ('a'|'A') | ('b'|'B') | ('c'|'C')
;

如果我从 RANGE2_VALUES 中删除值“5”它工作正常。谁能提示我做错了什么?

最佳答案

您必须意识到,词法分析器不会根据解析器尝试匹配的内容生成标记。因此,在您的情况下,输入 "5"将始终被标记为 RANGE1_VALUES永远不会作为 RANGE2_VALUES因为RANGE1_VALUESRANGE2_VALUES可以匹配此输入但 RANGE1_VALUES首先出现(所以 RANGE1_VALUES 优先于 RANGE2_VALUES )。

一个可能的解决方法是同时删除 RANGE1_VALUESRANGE2_VALUES规则并将它们替换为以下词法分析器规则:

D0_4
: '0'..'4'
;

D5
: '5'
;

D6_50
: '6'..'9' // 6-9
| '1'..'4' '0'..'9' // 10-49
| '50' // 50
;

A_B_C
: ('a'|'A')
| ('b'|'B')
| ('c'|'C')
;

并引入这些新的解析器规则:

range1_values
: D0_4
| D5
| D6_50
;

range2_values
: A_B_C
| D5
;

并更改所有RANGE1_VALUESRANGE2_VALUES使用 range1_values 调用解析器规则和 range2_values分别。

编辑

与其尝试在词法分析器级别解决这个问题,您可以简单地匹配任何整数值并在解析器规则内部检查该值是否是正确的(或正确的范围)使用 < em> semantic predicate :

range1_values
: INT {Integer.valueOf($INT.text) <= 50}?
;

range2_values
: A_B_C
| INT {Integer.valueOf($INT.text) == 5}?
;

INT
: '0'..'9'+
;

A_B_C
: 'a'..'c'
| 'A'..'C'
;

关于c# - 2 个不同域值中的 ANTLR3 公共(public)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7404132/

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