2014-04-20 49 views
1

我已經編寫了一個詞法分析器和分析器來分析線性代數語句。每個語句由一個或多個表達式組成,後跟一個或多個聲明。我使用menhir和OCaml來編寫詞法和解析器。使用menhir和OCaml重載乘法

例如: Ax = b,其中A是可逆的。

這應被理解爲A * X = B,(A,可逆)

表達式中的所有的ID必須是一個大寫或小寫的符號。我想重載乘法運算符,以便用戶不必輸入'*'符號。但是,由於詞法分析器也需要能夠讀取字符串(例如在本例中爲「可逆」),因此表達式的「Ax」部分作爲字符串發送到解析器。這會導致解析器錯誤,因爲在語句的表達式部分中不應該遇到任何字符串。

這裏是語法

stmt := 
    | expr "." 
    | decl "." 
    | expr "," decl "." 

expr := 
    | term 
    | unop expr 
    | expr binop expr 

term := 
    | <int> num 
    | <char> id 
    | "(" expr ")" 

decl := 
    | id "is" kinds 

kinds := 
    | <string> kind 
    | kind "and" kinds 

的基本思想是有一些方法來單個字符分開,並告訴他們應該被視爲乘法解析器?有沒有辦法改變詞法分析器,以便足夠聰明地知道逗號前的所有字符集都是id,並且之後的所有集羣都應該被視爲字符串?

回答

3

在我看來,你有兩個問題:

  1. 您希望您的詞法分析器在不同的地方不同的方式處理的字符序列。

  2. 您希望乘法由鄰接表達式指示(中間沒有操作符)。

我會在詞法分析器中解決的第一個問題。

一個問題是爲什麼你說你需要使用字符串。這意味着你可以說一些完全開放的東西。這可能是事實,但如果你能限制自己的數量,你可以使用關鍵字而不是字符串。例如,invertible將是一個關鍵字。

如果你真的想在這些地方允許任何字符串,那麼仍然有可能破解一個詞法分析器,以便它維護一個描述它所看到的狀態的狀態,並且展望未來會發生什麼。如果您不需要遵循預定義的語法,則可以調整語法以使其更容易。 (例如,你可以只用一個逗號。)

對於第二個問題,我想說你需要給語法添加鄰接關係。也就是說,你的語法需要一個規則,如term := term term。我懷疑讓它正確工作很困難,但它在OCaml(其中相鄰表達式表示函數應用程序)和awk(其中相鄰表達式表示字符串串聯)中工作。

+0

我的合作伙伴和我碰到的解決方案是在詞法分析器中定義關鍵詞,使它們不能成爲大詞彙的一部分。所以「in」中的「in」不會註冊爲關鍵字(因爲它後面有一個字符)。有沒有一個標準的方法來做到這一點? –