2015-11-01 35 views
0

我寫了下面的BNF「代碼」,它試圖用BNF描述簡單的數學。我遇到的問題是我不知道如何添加括號(括號)。使用BNF表示簡單的數學

Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"; 
Digits ::= <Digit>|<Digit><Digit>; 
Number ::= <Digits>|<Digits>.<Digits>; 

Addition ::= <Value> + <Value>; 
Subtraction ::= <Value> - <Value>; 
Multiplication ::= <Value> * <Value>; 
Division ::= <Value>/<Value>; 
Value ::= <Number>|<Addition>|<Subtraction>|<Multiplication>|<Division>; 

的另一個問題是,我不知道該BNF是100%正確的,因爲Value「說明」不看我的權利。

回答

1
Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"; 
Digits ::= <Digit>|<Digit><Digits>; 
Number ::= <Digits>|<Digits>.<Digits>; 
Operator ::= "+" | "-" | "*" | "/" 
Bracket_Left ::= "(" 
Bracket_Right ::= ")" 
Value ::= <Number>|<Bracket_Left><Value><Bracket_Right>|<Value><Operator><Value> 

也許不是最優雅的解決方案,但應該工作。始終記住遞歸的力量。

+0

哇,這比我的簡單得多!謝謝!是否有理由使用'Bracket_Left'和'Bracket_Right',而不是將它們直接插入'Value'定義中? –

+0

其實沒有那麼多 - 我只是想區分基本定義和派生的:)強迫症大聲笑 – 2015-11-02 00:45:47

+0

它是有道理的,我想我會保持這種方式。謝謝! –

0

如果你是運算符優先級之後也一樣,你應該用遞歸使用衆所周知的方法(在我的例子正確的):

AddSub ::= <MulDiv> ("+" | "-") <AddSub> | <MulDiv>; 
MulDiv ::= <Brackets> ("*" | "/") <MulDiv> | <Brackets>; 
Brackets ::= "(" <AddSub> ")" | <Decimal>; 
Decimal ::= <Integer> "." <Integer> | <Integer>; 
Integer ::= <Digit> <Integer> | <Digit>; 
Digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"; 

和運算符優先級自動執行分析器,無需進一步干預。我沒有發明這種方法,它在那裏已經有幾十年了,但我不得不承認它很親切。