[英]ANTLR ambiguous grammar?
我有幾個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分配元素標簽來在規則本身中產生〜('=')
我現在不記得語法,因為它已經超過10年,但ANTLR的一個主要優勢是具有回溯的任意長度前瞻。 所以,每當你看到一個雙引號時,就先看看是否匹配element
。 如果是,則將流作為element
; 如果沒有,則回退到STRING_LITERAL
規則。
我深入研究了ANTLR參考指南,並找到了句法謂詞示例。 改編它,我認為你的規則看起來像這樣:
protected
STRING : whatever...
;
protected
EXPRESSION: whatever...
;
STRING_OR_EXPR
: ( EXPRESSION ) => EXPRESSION { $setType(EXPRESSION); }
| STRING { $setType(STRING); }
;
鑒於它在SO網頁上的顯示方式,很難說,解析器有效地接收了什么,並且可能給出了為emphais添加的引號。 所以請原諒這個猜測,但是如果ANTLR有效的話
"variable_name" = "array[3]"
(注意引號),這將作為兩個由等號分隔的STRING_LITERAL標記響起,它可能沒有任何規則。
variable_name = "array[3]"
或者更好
variable_name = array[3]
是你想要做的。
編輯 :
在澄清該名稱是STRING (在別處定義,沒有引號)之后,很明顯上述猜測“開始”是正確的。 但是,另一個問題是,除非在STRING_LITTERAL中使用禁止的字符定義表達式 ,否則math_formula將與它不明確,因此詞法分析器將看不到一個元素,而是一個“name”=“STRING_LITERAL”序列,它沒有規則。
你試圖解析什么樣的搞搞語言? 我冒昧地猜測你最好的選擇是沿着這些方向你的詞法分析器添加一些狀態:
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比較熟悉
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.