我想解析純文本註釋並在其中查找特定標籤。該類型的標籤我在尋找的樣子:從任意純文本中抽取特定標籤
<name#1234>
其中 「名」 是[A-Z]字符串(從一個固定的列表)和 「1234」 代表[0-9] +號。這些標籤可以出現在零次或多次字符串中,並被任意其他文本包圍。例如,下列字符串都是有效的:
"Hello <foo#56> world!"
"<bar#1>!"
"1 < 2"
"+<baz#99>+<squid#0> and also<baz#99>.\n\nBy the way, maybe <foo#9876>"
以下字符串都是無效的:因爲「notinfixedlist」是不受支持的命名標識
"1 < 2"
"<foo>"
"<bar#>"
"Hello <notinfixedlist#1234>"
最後一個是無效。
我可以很容易地解析此使用簡單的regex,例如(我省略爲了簡單起見命名組):
<[a-z]+#\d+>
或直接指定一個固定的列表:
<(foo|bar|baz|squid)#\d+>
但我'd喜歡使用antlr的原因如下:
- 我想要任何與該格式不匹配的東西導致解析錯誤,所以如果文本包含「<」或「>」但與模式不匹配,則失敗。這些字符必須轉義爲「& lt;」和「& gt」;如果它不是標籤的話。
- 爲了支持其他類型的模式(例如:「{foo + 666}」或「[[1234]]」,我可能會擴展它,並希望避免正則表達式的爆炸。文件我可以擴展將是巨大的。
- 我喜歡antlr4實現訪問者模式,當遇到,而不必砍一起變化的正則表達式的特定類型的標籤我的代碼被調用的事實。
我如何使用antlr4實現這樣的語法?我見過的大多數例子都是針對整個文本遵循精確規則的語言,而我只希望語法適用於任意文本中的匹配模式。
我來到了這一點,我相信這是正確的:
grammar Tags;
parse
: (tag | text)*
;
tag
: '<' fixedlist '#' ID '>'
;
fixedlist
: 'foo'
| 'bar'
| 'baz'
| 'squid';
text
: ~('<' | '>')+
;
ID
: [0-9]+
;
這是正確的嗎?
很好地提出了問題,但不適合SO,因爲它主要是基於意見的。 – itsme86
好點。我將修改這個問題,具體問一下如何在antlr中實現。 –
你可能只需要兩個規則就可以讓你的詞法分析器:一個標籤和一個CHAR,然後語法就是一個'(TAG | CHAR)*'。 – Jacob