[英]Use token tokens in ANTLR4
我遇到了 ANTLR 的問題,我想知道這樣的情況在 ANTLR 中是否可以接受。 我在下面准備了一個非常簡單的例子。
grammar test;
test
: statement*
;
statement
: s1
| s2
;
s1
: 'OK' INT
;
s2
: 'ABC' US_INT
;
INT
: S_INT
| US_INT
;
S_INT
: [+-] [0-9]+
;
US_INT
: [0-9]+
;
對於OK 5
一切正常,但對於ABC 5
我收到以下錯誤:
line 1:4 mismatched input '5' expecting US_INT
我正在使用-tokens
選項運行grun
並且我在這里使用INT
而不是US_INT
[@1,4:4='5',<INT>,1:4]
這讓我懷疑在 ANTLR 中是否可能出現這種情況。 以前,我嘗試重新排序令牌,將US_INT
從INT
、片段和其他一些東西中移出,但效果不佳。 唯一的變化是OK 5
停止工作而ABC 5
啟動。 我希望這兩種情況都能正常工作。
您面臨的問題很簡單: 5
可以同時匹配: US_INT
(因為它包含US_INT
)和S_INT
本身。 但是,只要INT
被聲明為高於US_INT
,詞法分析器就會將5
解析為INT
。
為了解決它,我建議您將INT
從詞法分析器標記移動到解析器規則,如下所示:
grammar test;
test
: statement*
;
statement
: s1
| s2
;
s1
: 'OK' int_stmt
;
s2
: 'ABC' US_INT
;
int_stmt
: S_INT | US_INT
;
S_INT
: [+-] [0-9]+
;
US_INT
: [0-9]+
;
如果你想逃避,在這種情況下,從詞法分析的優先級,你可以在 Tunnel Grammar Studio 中使用這個 ABNF 解析器語法,它根本沒有這個問題:
test = *statement
statement = s-ok / s-abc
s-ok = "OK" 1*ws int
s-abc = "ABC" 1*ws unsigned-int
int = signed-int / unsigned-int
signed-int = ('+' / '-') unsigned-int
unsigned-int = 1*('0'-'9')
ws = %x20 / %x9 / %xA / %xD
這是不區分大小寫匹配的情況,如 ABNF (RFC 5234) 中所定義。 您還可以將每個字符串的區分大小寫或不區分大小寫的匹配分別明確定義為%s"ABC"
或%i"ABC"
(RFC 7405)。 當你開始有更多的語句時,一些字符串會開始重疊,那么你可以在詞法分析器語法中讓自己成為關鍵字:
keyword = %s"OK" / %s"OK2"
並在解析器語法中執行以下操作:
s-ok = {keyword, %s"OK"} 1*ws int
s-ok-2 = {keyword, %s"OK2"} 1*ws int 1*ws int
s-ok-any = {keyword} 1*ws int *(ws 0*1 int)
請注意,最后一條規則將允許您在整數之間有任何空格,並且任何關鍵字都將匹配。
*我開發了 Tunnel Grammar Studio。 語法很簡單,所以演示可能對你來說已經足夠了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.