簡體   English   中英

如何在 Antlr4 Lexer 中匹配 [BOF]“文件開頭”?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM