我有几条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 | ~('\\'|'"') )* '"'
;
仍然不起作用,我也不知道如何通过为它或somthing分配元素标签来在规则本身中产生〜('=')
答案 0 :(得分:1)
我现在不记得语法,因为它已经超过10年,但ANTLR的一个主要优势是具有回溯的任意长度前瞻。因此,无论何时看到双引号,都要先查看匹配element
。如果是,则将流消费为element
;如果没有,请回到STRING_LITERAL
规则。
我深入研究了ANTLR参考指南,并找到了句法谓词示例。根据这一点,我认为你的规则看起来像这样:
protected
STRING : whatever...
;
protected
EXPRESSION: whatever...
;
STRING_OR_EXPR
: ( EXPRESSION ) => EXPRESSION { $setType(EXPRESSION); }
| STRING { $setType(STRING); }
;
答案 1 :(得分:0)
很难说,解析器有效地接收了什么,给出了它在这个SO网页上的显示方式,并且可能给出了为emphaisis添加的引号。所以原谅这个猜测,但是如果ANTLR有效地得到了
"variable_name" = "array[3]"
(注意引号),这将作为两个STRING_LITERAL标记分开,它们由等号分隔,可能没有任何规则。
variable_name = "array[3]"
或者更好
variable_name = array[3]
是你要做的。
修改强>:
在澄清该名称是 STRING (在别处定义,没有引号)之后,很明显上述猜测“开始”是正确的。但是,另一个问题是,除非 表达 定义为 STRING_LITTERAL 中禁止使用的字符,否则 < em> math_formula 对它不明确,因此词法分析器不会看到 元素 ,而是“name'='STRING_LITERAL”没有规则的序列。
答案 2 :(得分: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更熟悉