使用 BNF 表示简单的数学

Representing simple mathematics using BNF

我写了下面的 BNF "code",它试图用 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 "description" 在我看来不正确。

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

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