簡體   English   中英

匹配帶有空格的單詞作為一個標記,但不允許某些關鍵字標記

[英]match words with spaces as one token but disallow certain keyword tokens

我有以下令牌規則:

IF: 'IF' | 'if';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
BINARYOPERATOR: 'AND' | 'and' | 'OR' | 'or';
NOT: 'NOT' | 'not';

WORD: (DIGIT* (LOWERCASE | UPPERCASE | WORDSYMBOL)) (LOWERCASE | UPPERCASE | DIGIT | WORDSYMBOL)*;

這行得通,像my variable這樣的東西以WORD WORD形式出現。 我希望能夠只擁有一個代表整個事物的令牌。

我把它掛在:


IF: 'IF' | 'if';
THEN: 'THEN' | 'then';
ELSE: 'ELSE' | 'else';
BINARYOPERATOR: 'AND' | 'and' | 'OR' | 'or';
NOT: 'NOT' | 'not';

WORD: (LOWERCASE | UPPERCASE | WORDSYMBOL)+ (' '* (LOWERCASE | UPPERCASE | WORDSYMBOL))*;

這解決了這個問題,但是它也捕獲了我想分類為上述關鍵字標記的字符串。

例如if my variable then something應該只是單個WORD標記,它應該是IF WORD THEN WORD

我理解為什么要按原樣對其進行標記(首選消耗更多輸入的標記),但不確定如何更改行為。

不幸的是(對於您想做的事情),ANTLR 的標記化不是這樣工作的。

(這更像是一個“合乎邏輯”的解釋,而不是實際的實現)

當 ANTLR 評估 Lexer 規則時,它會嘗試將每個規則與輸入 stream 中的字符匹配,該輸入 stream 中以當前 position 開頭。

一旦它擁有所有匹配的輸入序列,如果有一個序列比 rest 長,它將選擇產生最長令牌的令牌類型。 這是您的WORD規則將使用輸入的地方,直到找到與WORD中的字符不匹配的內容(如果它們與WORD模式匹配,則將包括“slurping”關鍵字)。

(為了完整性)如果 Tokenizer 發現多個等長匹配,則在您的語法中匹配的第一個規則將是分配的 Token 類型。


您可能會通過以下方法獲得成功:

假設: WORD不能是您的語言關鍵字之一

  • 確保WORD規則位於所有關鍵字規則之后,以便它們優先。
  • 添加解析器規則word: WORD+;
  • 現在在您使用RULE標記的任何地方都使用 parser rule word
  • 編寫一個覆蓋enterWord()的偵聽器並將所有WORD合並為一個“單詞”。 (您可以通過多種方式處理此步驟,但這是一種相當簡單的方法)

警告:

  • 語言通常不允許這樣做是有原因的。 我懷疑你會在路上遇到其他並發症/模棱兩可。
  • 性能可能會受到影響,因為 ANTLR 必須做更多的預測才能知道何時回溯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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