2012-03-28 47 views
4

我使用CL-Lex實現詞法分析器(作爲CL-YACC的輸入),我的語言有幾個關鍵字,如「let」和「in」。然而,雖然詞法分析器認識到這些關鍵字,但它確實太多了。當它找到諸如「init」的單詞時,它將第一個標記返回爲IN,而它應該爲「init」字返回一個「CONST」標記。強制CL-Lex讀取整個單詞

這是詞法分析器的簡單版本:

(define-string-lexer lexer 
    (...) 
    ("in" (return (values :in [email protected]))) 
    ("[a-z]([a-z]|[A-Z]|\_)" (return (values :const [email protected])))) 

如何強制詞法分析器,直到出現一些空白,充分閱讀整個單詞?

回答

1

上面的示例詞法分析器有兩條規則,它們都與兩個字符的序列匹配。而且,它們具有共同的匹配(第二個匹配的語言是第一個的嚴格超集)。

在傳統的Unix lex中,如果兩個規則都匹配相同的輸入長度,則優先考慮規範中首先出現的規則。否則,最長可能的匹配占主導地位。

(雖然沒有RTFM,我不能說這是在CL-LEX會發生什麼,但它做什麼在這種情況下發生的合理的假設。)

它看起來像你錯過一個正則表達式Kleene算子在第二條規則中匹配較長的標記。

+1

我終於找到了一個解決方案。我在''中使用'\ b'運算符圍繞''in'的第一個模式,就像這個''\ bin \ b「'一樣。這基本上迫使詞法分析器將「in」看作單詞。 – 2012-03-28 18:31:45

8

這既是對Kaz的錯誤的糾正,也是對OP的信心投票。

在他最初的迴應中,Kaz指出Unix的優先順序恰好落後於Unix。從lex文檔:

Lex可以處理不明確的規格。當多於一個表達式可以 匹配當前輸入,萊克斯選擇如下:

  1. 最長匹配是優選的。

  2. 在匹配相同字符數的規則中,首先優先選擇 的規則。

此外,卡茲是錯誤的批評使用Perl正則表達式字邊界匹配的OP的解決方案。正如它發生的那樣,你被允許(免於折磨內疚)以任何方式匹配你的詞法發生器將支持的詞語。 CL-LEX使用Perl的正則表達式,它使用\b作爲一種方便的語法更加繁瑣lex近似的:

%{ 
#include <stdio.h> 
%} 

WC  [A-Za-z'] 
NW  [^A-Za-z'] 

%start  INW NIW 

{WC} { BEGIN INW; REJECT; } 
{NW} { BEGIN NIW; REJECT; } 

<INW>a { printf("'a' in wordn"); } 
<NIW>a { printf("'a' not in wordn"); } 

在同等條件下,尋找一種方法來明確匹配他的話,可能比選擇好。

儘管Kaz想要打他,但OP已經正確回答了他自己的問題,提出了一個利用他選擇的詞法分析器的靈活性的解決方案。