改善数学表达式的BNF

时间:2010-09-28 09:21:53

标签: parsing calculator bnf

学习编程的一个好习惯就是写一个计算器。为此,我在DSL中创建了某种BNF,并希望寻求您的帮助来改进它。使用这种小语言,您应该能够将addmultiplyassign值和表达式命名为(a.k.a.创建变量和函数)。

首先看看BNF的Hava:

<Program>     ::= <Line>(<NewLine><Line>)*
<Line>        ::= {"("}<Expression>{")"}|<Assignment>
<Assignment>  ::= <Identifier>"="<Expression>
<Identifier>  ::= <Name>{"("<Name>(","<Name>)*")"}
<Expression>  ::= <Summand>(("+"|"-")<Summand>)*
<Summand>     ::= <Factor>(("*"|"/")<Factor>)*
<Factor>      ::= <Number>|<Call>
<Call>        ::= <Name> {"("<Expression>(","<Expression>)*")"}
<Name>        ::= <Letter>(<Letter>|<Digit>)*
<Number>      ::= {"+"|"-"}(<Digit>|<DigitNoZero><Digit>+)
<Digit>       ::= "0"|<DigitNoZero>
<DigitNoZero> ::= "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
<Letter>      ::= [a-zA-Z]
<NewLine>     ::= "\n"|"\r"|"\r\n"

如您所见,此BNF在NewLine旁边没有空格。在解析开始之前,我计划从字符串中删除所有空格(当然在NewLine旁边)以进行解析。无论如何,它对于解析器来说并不是必需的。

当使用现在定义的语言时,有4件事可能导致问题,我希望你能帮我找出合适的解决方案:

  1. 我尝试按照自上而下的方法生成此gramar,但<Expression><Summand><Factor><Call>之间有一个圆圈。
  2. gramar以完全相同的方式处理变量和函数。大多数编程语言都有所不同。 在这里区分是否有必要?
  3. 在尝试实施BNF时,可能会有一些我不知道的关于编程的事情,BNF,等等,以后会杀了我。但是在我开始之前你可能会发现它。
  4. 我可能找不到一些简单而愚蠢的错误。对不起,那个案子。我希望不再有这些错误。
  5. 使用手和脑我可以成功解析以下测试用例:

    "3"
    "-3"
    "3-3"
    "a=3"
    "a=3+b"
    "a=3+b\nc=a+3"
    "a(b,c)=b*c\ra(1+2,2*3)"
    

    请帮助改进BNF,它可用于成功编写计算器。

    修改 这个BNF真的没有完成。它不会将案例“2 + -3”(应该失败,但不会)和“2 +( - 3)”(不应该失败,但确实如此)正确处理。

1 个答案:

答案 0 :(得分:2)

  

gramar以完全相同的方式处理变量和函数。大多数编程语言都有所不同。在这里区分是否有必要?

能够将函数调用的结果局部变量或常量表达式完全相同,这正是定义(数学)函数的关键所在。第一名。我无法想象使用允许函数但不处理的语法

1 + 1

完全相同
1 + a

1 + sin(x)