我的PERL語法有一個問題,以下是我的語法的相關部分:
我的PERL語法有一個問題。
element
: element (ASTERISK_CHAR | SLASH_CHAR | PERCENT_CHAR) element
|詞
;
SLASH_CHAR: '/'。
REGEX_STRING
: '/'/span> (~('/'/span> | '
' | '
') | NEW_LINE)* '/' * '/'
;
片段 NEW_LINE
: '
'? '
'/span>
;
如果REGEX_STRING規則沒有被注釋,那么下面的perl就不能決議 :
$b = 1/2。
$c = 1/2;
<2021/8/20-19: 24:37> <ERROR> [決議。 AntlrErrorLogger] - Unit 1: <unknown> :2:6: extraneous input '/2;
$c = 1/'期待{<EOF> , '='/span>, '**='/span>, ' ='/span>, '-='/span>, ' 。 =', '*=', '/=', '%=', CROSS_EQUAL, '& =', '|=', '^=', '& . =', '|.=', '^. =', '<<=', '>>=', '&&。 =', '||=', '//=', '==', '> =', '<=', '<=>', '<>', '! ='/span>, '>'/span>, '< ', '~~', ' ', '--', '**', ' 。 ', ' '/span>, '-', '*', '/', '%', '=~', '! ~', '&&', '||', '//', '&', '&. ', '|', '|。', '^', '^。 , '<<', '>>', '...', ' 。 ', '? ', ';', X_KEYWORD, AND, CMP, EQ, FOR, FOREACH, GE, GT, IF, ISA, LE, LT, OR, NE, UNLESS, UNTIL, WHEN, WHILE, XOR, UNSIGNED_INTEGER }
注意,在哪里使用REGEX_STRING這個詞法規則并不重要,即使它沒有出現在決議器規則的任何地方,只要出現在這里就會使決議失敗(所以問題出在決議器方面)。 如果我去掉詞典規則REGEX_STRING,那么它就會被決議得很好,但是我不能決議 :
$dateCalc =~ /^([0-9]{4})([0-9]{2})([0-9]{2})/
另外,我注意到這個perl決議,所以第一個和第二個'/'之間似乎有某種互動。
$b = 12; # removeed the / between 1 and 2
$c = 1/2; # 洗掉這里的/也可以。
我似乎找不到如何撰寫我的重碼詞法規則,以避免使一些東西失敗。 我錯過了什么?我怎樣才能很好地決議這兩個運算式呢?
uj5u.com熱心網友回復:
這里的基本問題是,ANTLR4,像許多其他決議框架一樣,執行獨立于語法的詞法分析;無論哪種標記可能被決議器接受,都會產生相同的標記。因此,詞法分析器必須決定一個給定的/是一個除法運算子還是一個重碼的開始,這個決定實際上只能用句法資訊來做。(有一些決議框架沒有這個限制,因此可以用來實作無掃描器決議器。這些包括基于 PEG 的決議器和 GLR/GLR 決議器。
在ANTLR4 示例目錄中,有一個解決這種詞義模糊性的例子,它也出現在決議 ECMAScript 中。(這是一個github的固定鏈接,這樣下面參考的行號就可以繼續使用。)
基本的策略是:在一個新的環境中,我們需要一個新的策略。
基本策略是根據緊接著的前一個標記來決定/是否可以開始一個正則運算式。這在ECMAScript中是可行的,因為運算子(如/或/=)可以出現的語法環境與運算子可以出現的環境是不相干的。這可能不會直接轉化為Perl決議器,但它可能有助于展示各種可能性。
第780-782行:regex令牌本身受到語意保護:
RegularExpressionLiteral
: {isRegexPossible()}? '/'/span> RegularExpressionBody '/'/span> RegularExpressionFlags
;
第154-182行:守護函式本身很簡單,但顯然需要一定的語法分析來生成正確的測驗。(注意:代幣的清單已經被縮寫了,完整的清單見原始檔案):
<private boolean isRegexPossible() {
if (this.lastToken == null) {
return true;
}
switch (this.lastToken.getType()) {
case Identifier:
case NullLiteral:
...
// 在上述任何一個token之后,no regex literal can follow.
return false。
默認情況下。
// 在所有其他情況下,一個regex字面_是_可能的。
return true。
}
}
第127-147行為了使其發揮作用,掃描器必須在成員變數last_token中保留之前的令牌。(為了節省空間,注釋被洗掉了):
@Override
public Token nextToken() {
Token next = super.nextToken()。
if (next.getChannel() == Token.DEFAULT_CHANNEL) {
this.lastToken = next;
}
return next;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/311370.html
標籤:
