使用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的"描述"在我看来不正确。

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>

也许不是最优雅的解决方案,但应该有效。永远记住递归的力量。

如果你也追求运算符优先级,你应该使用众所周知的递归方法(在我的例子中是正确的):

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";

语法分析器自动遵循运算符优先级,无需进一步干预。这种方法不是我发明的,它已经存在了几十年,但我不得不承认它有点温和。

最新更新