3

我有几个 ANTLR 规则,我不知道如何使它们起作用

第一条规则是:

STRING_LITERAL
    :  '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

第二条规则是:

element 
 :  name '='  math_formula  ;
math_formula
        :        '"' expression '"';

该表达式是一个类似于 C 的正则表达式

语法示例

 "count" = "array[3]"

count 应该是一个字符串,而 array[3] 应该是一个表达式

我的问题是词法分析器总是将“count”和“array[3]”作为字符串返回,而 Parser 无法识别表达式。

我正在使用java目标。

编辑:将“variable_name”更改为“count”。

EDIT2:在下面解释了我的第二次尝试:

我可以用 '= "' 检测到表达式的开头,但是我无法在 Lexer 中检测到表达式的结尾,当我有 2 个由 ',' 分隔的元素时会导致错误检测字符串

"count1" = "array[1]",
"count2" = "array[2]"

如果我使用 '= "' 作为 START_EXPRESSION,词法分析器检测到结束第一个表达式的引号,并且将第二个字符串开头的引号检测为字符串 ",\n",这显然是不正确的。

编辑 3:尝试句法谓词

我将 STRING_LITERAL 的规则更改为

STRING_LITERAL  
    :   (~('=') '"' ( EscapeSequence | ~('\\'|'"') )* '"')=> '"' ( EscapeSequence | ~('\\'|'"') )* '"'
    ;

仍然不起作用,我也不知道如何通过为其分配元素标签或其他东西来在规则本身中生成 ~('=')

4

3 回答 3

1

我现在不记得语法了,因为它已经 10 多年了,但是 ANTLR 的主要优势之一是带有回溯的任意长度的前瞻。因此,每当您看到双引号时,请提前查看是否匹配element. 如果是,则将流作为element; 如果不是,则退回到STRING_LITERAL规则。


我深入研究了 ANTLR 参考指南,并找到了句法谓词示例。适应它,我认为你的规则看起来像这样:

protected
STRING : whatever...
;
protected
EXPRESSION: whatever...
;
STRING_OR_EXPR
: ( EXPRESSION ) => EXPRESSION { $setType(EXPRESSION); }
| STRING { $setType(STRING); }
;
于 2009-10-08T16:41:46.753 回答
0

您要解析哪种怪异的语言?我冒昧地猜测您最好的选择是按照以下方式向您的词法分析器添加一些状态:

ASSIGN:
    ('=' '"')=> /* assuming whitespace doesn't exist */
     '=' {some_global_flaggy_thing=1;}
    |'='
    ;
STRING_LITERAL:
    {some_global_flaggy_thing==1}? '"' {$type=QUOTE; some_gobal_flaggy_thing=2;}
    |{some_global_flaggy_thing==2}? '"' {$type=QUOTE; some_global_flaggy_thing=0;}
    | '"' /* normal string literal stuff */ '"'
    ;

当然,您的嵌入式表达式中不能包含字符串文字。
注意我更熟悉ANTLR2

于 2009-10-10T03:59:34.160 回答
0

很难说解析器有效地接收了什么,考虑到它在这个 SO 网页上的显示方式,并且可能给出了你为强调而添加的引号。所以请原谅这个基本的猜测,但如果 ANTLR 有效地得到

"variable_name" = "array[3]"

(注意引号),这将作为两个 STRING_LITERAL 标记由等号分隔,它可能没有任何规则。

variable_name = "array[3]"

或者更好

variable_name = array[3]

是你想要做的。

编辑
在澄清该名称是一个字符串(在别处定义,没有引号)之后,很明显上述猜测“开始”是正确的。然而,另一个问题是,除非表达式是用STRING_LITERAL中禁止的字符定义的,否则math_formula将与它不明确,因此词法分析器不会看到一个元素 ,而是一个它没有的“name '=' STRING_LITERAL”序列规则。

于 2009-10-08T16:49:47.983 回答