我正试图找出任何数学表达式的语法规则。
我正在使用EBNF(下面链接的wiki文章)来推导语法规则。
我设法提出了一段有效的方法,但语法规则失败了onScreenTime + (((count) - 1) * 0.9)
。
规则如下:
math ::= MINUS? LPAREN math RPAREN
| mathOperand (mathRhs)+
mathRhs ::= mathOperator mathRhsGroup
| mathOperator mathOperand mathRhs?
mathRhsGroup ::= MINUS? LPAREN mathOperand (mathRhs | (mathOperator mathOperand))+ RPAREN
您可以放心地假设mathOperand
是正数或负数或变量。
您还可以假设mathOperator
表示任何数学运算符,如+或 - 。
此外,LPAREN
和RPAREN
分别为'('和')'。
EBNF: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form
修改
忘了提及(count) - 1
失败了。它表示RPAREN
而不是- 1
。
编辑2 我修订的EBNF现在看起来像这样:
number ::= NUMBER_LITERAL //positive integer
mathExp ::= term_ ((PLUS | MINUS) term_)* // * is zero-or-more.
private term_ ::= factor_ ((ASTERISK | FSLASH) factor_)*
private factor_ ::= PLUS factor_
| MINUS factor_
| primary_
private primary_ ::= number
| IDENTIFIER
| LPAREN mathExp RPAREN
答案 0 :(得分:3)
查看任何编程语言的表达式语法:
Empty
指数作为练习留给读者:注意取幂运算符是右关联的。这是 yacc 表示法。注意您使用的是EBNF,而不是BNF。
编辑我的非左递归EBNF不如我的expression
: term
| expression '+' term
| expression '-' term
;
term
: factor
| term '*' factor
| term '/' factor
| term '%' factor
;
factor
: primary
| '-' factor
| '+' factor
;
primary
: IDENTIFIER
| INTEGER
| FLOATING_POINT_LITERAL
| '(' expression ')'
;
那么强,但要分解左递归,您需要一个方案,例如:
yacc
等,其中expression
::= term ((PLUS|MINUS) term)*
term
::= factor ((FSLASH|ASTERISK) factor)*
表示零或更多'。我对此的评论大多不正确,应予以忽略。
答案 1 :(得分:0)
您可能需要查看通常使用递归下降解析器实现的语言表达式语法,其中需要LL(1)语法,不允许左递归。 Wirth的大多数语言都属于这一类。以下是经典Modula-2的语法示例。 EBNF链接显示在每个规则旁边。
http://modula-2.info/m2pim/pmwiki.php/SyntaxDiagrams/PIM4NonTerminals#expression