[英]How to match [BOF]"Begin of file" in Antlr4 Lexer?
在一個 Antlr4 語法中,我需要注釋 ( // xxxx
) 始終位於一行的開頭。 以下語法適用於大多數情況。
grammar com;
comment: COMMENT;
COMMENT
: '\n' '//' .*? '\n'
;
按照設計,它將匹配\n//comment\n
但不匹配//comment\n
。 但我也希望它匹配<BOF>//comment\n
。 我該如何實施?
您可能會發現,在您的 parseTree 的語義驗證過程中,此編輯在解析后處理得更好。 (注意:不要求解析器只識別有效輸入,只是它正確解釋理解該輸入的唯一方法。)
例如,如果// might be a comment
有其他的替代解釋?
如果不是,我可能只接受// comment...\n
作為標記,而不管該行中的 position。
然后,一旦你有了解析樹,你就可以檢查你的comment
是否總是有一個 0 列。這樣做,你的語法就不會綁定到特定的目標語言,而且,也許更重要的是,你可以給出一個“ nice”錯誤消息,例如“注釋必須從一行的第一列開始”。
如果您嘗試在 Lexer(或解析器)中處理它,那么,如果它不在正確的列中,您將得到一個更遲鈍的識別錯誤,用戶將更難以理解。
這在與語言無關的方式中是不可能的。 您將必須在語法中添加目標特定代碼並使用謂詞來檢查 char position 是否為 0:
COMMENT
: {getCharPositionInLine() == 0}? '//' ~[\r\n]*
;
OTHER
: .
;
如果您現在標記輸入:
// start
// middle
?//...
// end
使用 Java 代碼:
String input = "// start\n// middle\n?//...\n// end";
comLexer lexer = new comLexer(CharStreams.fromString(input));
CommonTokenStream stream = new CommonTokenStream(lexer);
stream.fill();
for (Token t : stream.getTokens()) {
System.out.printf("%-10s'%s'%n",
comLexer.VOCABULARY.getSymbolicName(t.getType()),
t.getText().replace("\n", "\\n"));
}
以下內容將打印到您的控制台:
COMMENT '// start'
OTHER '\n'
COMMENT '// middle'
OTHER '\n'
OTHER '?'
OTHER '/'
OTHER '/'
OTHER '.'
OTHER '.'
OTHER '.'
OTHER '\n'
COMMENT '// end'
EOF '<EOF>'
請注意,我還刪除了COMMENT
末尾的\n
,否則輸入末尾的注釋將不匹配。
我如何使用 JavaScript 做到這一點? 我在 inte.net 上找不到很好的例子。
通過查看Javascript 來源,它看起來像{this.column === 0}?
Javascript 相當於{getCharPositionInLine() == 0}?
順便問一下,Intellij Plugin 支持預測嗎? 如果支持,是否只支持 Java?
不,IntelliJ 插件會忽略謂詞。 畢竟,謂詞中的代碼可以是任意代碼塊,因此很難支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.