2012-10-13 38 views
3

我正在研究數學表達式解析器的Bison文件。到目前爲止它基本上都很好,但我正面臨一個隱式乘法的問題。我怎麼能與野牛有一個「隱式乘法」規則?

你好,我想支持這個表達式,如2x sin(4x) cos(4x)。它應該解析爲2 * x * sin(4 * x) * cos(4 * x)。沒有什麼太糟糕了這裏,但考慮下面的一組規則:

expr 
    : /* snip */ 
    | '-' expr  { /* negate expression */ } 
    | expr '-' expr { /* subtract expressions */ } 
    | expr expr  { /* multiply expressions */ } 

有了這樣的隱含乘法法則與減法規則將導致不確定性:是x - log(x)log(x)x減法或x通過-log(x)乘法?

我已經準備好迎接一個簡單的解決方案,比如「這是一個乘法,除非它正在減去」,但我不知道如何告訴Bison。

回答

4

隱含乘法規則產生與減法規則之間的歧義:x-log(x)將log(x)與x相減,或將x乘以-log(x)?

或甚至是x - l * o * g * x?或者,也許只是x - log * x

所以不是一個簡單的問題。假設你可以通過查看log來判斷它是一個函數。然後,您可以在詞法分析器中消除歧義,並且「如果有疑問,看起來像是中綴操作符的操作符是中綴操作符」。這裏有一個快速的解決方案:

term : ID 
     | NUMBER 
     | '(' expr ')'  { $$ = $2; } 
     | FUNC '(' expr ')' { $$ = new_expr($1, 'c', $3); } 
     ; 

factor : term 
     | term factor  { $$ = new_expr($1, '*', $2); } 
     ; 

prefix : factor 
     | '-' factor  { $$ = new_expr(0, '-', $2); } 
     ; 

muldiv : prefix 
     | muldiv '/' prefix { $$ = new_expr($1, '/', $3); } 
     | muldiv '*' prefix { $$ = new_expr($1, '*', $3); } 
     ; 

expr : muldiv 
     | expr '+' muldiv { $$ = new_expr($1, '+', $3); } 
     | expr '-' muldiv { $$ = new_expr($1, '-', $3); } 
     ; 

這種特殊的語法不允許--X,雖然這是爲Y完全滿意 - X,這也就是說,Y - ( - X)。如果您想接受-x,則可以將第二個prefix生產更改爲'-' prefix

就個人而言,我寧願能夠輸入sin 2xlog 3n,但開始有點棘手。 sin 2x cos 2x是什麼意思?據推測,這意味着(sin(2*x))*(cos(2*x))。但是log nlog n是不是意思是log(n*log(n))?這一切都可以實現;它只是需要思考所有的可能性。

+0

嗯,它不是'x * l * o * g',因爲我的詞法分析器將「log」(以及所有支持的函數名稱)視爲不同的標記,我的分析器使用特定的規則處理函數。 – zneak

+0

@zneak,是的,我猜對了。因此,在我的語法中使用FUNC作爲詞法標記:) – rici