看看有没有写BNF文法表达式部分的理论
Find out if there is a theory fow writing expression section of BNF Grammar
我想为数学程序编写一个新的解析器。当我为此编写 BNF 语法时,我陷入了表达式。这是我写的BNF符号。
program : expression*
expression: additive_expression
additive_expression : multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
multiplicative_expression : number
| number '*' multiplicative_expression
| number '/' multiplicative_expression
但是我无法理解如何为 ++, --, +=, -=, &&, || etc.
这个运算符编写 BNF 表达式语法。我指的是 C、C++、C#、Python、Java 等语言中的运算符
我知道在使用+, -, *, /
运算符时,语法应该按照BODMAS理论来写。
我想知道的是,写其他运算符的语法是否应该用到什么理论?
我仔细看了 C++ 语言 语法(表达式部分)。但是我看不懂。
<expression> ::= <assignment_expression>
| <assignment_expression> <expression>
<assignment_expression> ::= <logical_or_expression> "=" <assignment_expression>
| <logical_or_expression> "+=" <assignment_expression>
| <logical_or_expression> "-=" <assignment_expression>
| <logical_or_expression> "*=" <assignment_expression>
| <logical_or_expression> "/=" <assignment_expression>
| <logical_or_expression> "%=" <assignment_expression>
| <logical_or_expression> "<<=" <assignment_expression>
| <logical_or_expression> ">>=" <assignment_expression>
| <logical_or_expression> "&=" <assignment_expression>
| <logical_or_expression> "|=" <assignment_expression>
| <logical_or_expression> "^=" <assignment_expression>
| <logical_or_expression>
<constant_expression> ::= <conditional_expression>
<conditional_expression> ::= <logical_or_expression>
<logical_or_expression> ::= <logical_or_expression> "||" <logical_and_expression>
| <logical_and_expression>
<logical_and_expression> ::= <logical_and_expression> "&&" <inclusive_or_expression>
| <inclusive_or_expression>
<inclusive_or_expression> ::= <inclusive_or_expression> "|" <exclusive_or_expression>
| <exclusive_or_expression>
<exclusive_or_expression> ::= <exclusive_or_expression> "^" <and_expression>
| <and_expression>
<and_expression> ::= <and_expression> "&" <equality_expression>
| <equality_expression>
<equality_expression> ::= <equality_expression> "==" <relational_expression>
| <equality_expression> "!=" <relational_expression>
| <relational_expression>
<relational_expression> ::= <relational_expression> ">" <shift_expression>
| <relational_expression> "<" <shift_expression>
| <relational_expression> ">=" <shift_expression>
| <relational_expression> "<=" <shift_expression>
| <shift_expression>
<shift_expression> ::= <shift_expression> ">>" <addictive_expression>
| <shift_expression> "<<" <addictive_expression>
| <addictive_expression>
<addictive_expression> ::= <addictive_expression> "+" <multiplicative_expression>
| <addictive_expression> "-" <multiplicative_expression>
| <multiplicative_expression>
<multiplicative_expression> ::= <multiplicative_expression> "*" <unary_expression>
| <multiplicative_expression> "/" <unary_expression>
| <multiplicative_expression> "%" <unary_expression>
| <unary_expression>
<unary_expression> ::= "++" <unary_expression>
| "--" <unary_expression>
| "+" <unary_expression>
| "-" <unary_expression>
| "!" <unary_expression>
| "~" <unary_expression>
| "size" <unary_expression>
| <postfix_expression>
<postfix_expression> ::= <postfix_expression> "++"
| <postfix_expression> "--"
| <primary_expression>
<primary_expression> ::= <integer_literal>
| <floating_literal>
| <character_literal>
| <string_literal>
| <boolean_literal>
| "(" <expression> ")"
| IDENTIFIER
<integer_literal> ::= INTEGER
<floating_literal> ::= FLOAT
<character_literal> ::= CHARACTER
<string_literal> ::= STRING
<boolean_literal> ::= "true"
| "false"
你能帮我理解一下吗?我在互联网上搜索了很多关于这个的内容。但是我找不到合适的解决方案。
谢谢
我想问题不在于你不知道如何编写 BNF 语法。相反,您不知道应该编写哪种语法。换句话说,如果有人告诉您运算符的优先顺序,您可以毫不费力地写下解析具有该特定优先顺序的运算符的语法。但是您不知道应该使用哪种优先顺序。
不幸的是,没有关于运算符优先级的国际高级委员会,我所知道的任何宗教也没有提供精神参考,包括神圣启发的运算符优先级规则。
对于某些运算符,优先顺序相当明确:例如,采用 BODMAS 是有充分理由的,但主要原因是大多数人已经根据这些规则编写了算术。你当然可以根据群论提出一个看似合理的数学论证,说明为什么乘法优先于加法似乎很自然,但总会有人怀疑这个论证是根据 post facto 来证明 already-made 决定的合理性。尽管如此,使乘法绑定比加法更紧密的论点也适用于 bitwise-and 优先于 bitwise-or,或 boolean-and 优先于 boolean-or。 (尽管我注意到 C 编译器编写者不相信程序员会有那种特殊的直觉,因为如果您在此类表达式中省略多余的括号,大多数现代编译器都会发出警告。)
我认为几乎每个人都会同意的一个优先关系是直观的,即算术运算符优先于比较运算符,比较运算符优先于运算符优先于布尔运算符。大多数程序员会发现一种语言选择将 a > b + 7
解释为意思是“将 a
与 b
进行比较的布尔值加七”。同样,以 (a > 0) || (b > 0)
以外的任何方式解释 a > 0 || b > 0
可能被认为是离谱的。但是其他优先级选择似乎更加随意,并且并非所有语言都使它们相同。 (例如“不等于”和“大于”的相对优先级,或者“异或”和“异或”的相对优先级。
那么语言设计新手应该做什么呢?好吧,首先求助于您自己的直觉,特别是如果您经常使用相关运算符。此外,询问您的朋友、联系人和潜在的语言用户他们的想法。看看其他语言做了什么,但要用批判的眼光看待。在 language-specific 论坛上搜索投诉。很可能是最初的语言设计者做出了一个不幸的(甚至是愚蠢的)选择,现在不能改变这个选择,因为它会破坏太多现有的程序。 (这就是为什么您担心运算符优先级是一件好事:弄错可能会带来严重的未来问题。)
直接实验也有帮助,尤其是对于很少一起使用的运算符。使用运算符定义一个似是而非的表达式,然后根据各种可能的规则将其写出两次(或更多次),省略括号。哪一个看起来更容易理解? (再次招募你的朋友并问他们同样的问题。)
如果最后实在无法决定某对运算符之间的优先顺序是什么,可以考虑另一种解决方案:让这些运算符必须有括号。 (这是 C 编译器抱怨在布尔表达式中省略多余括号的意图。)
我想为数学程序编写一个新的解析器。当我为此编写 BNF 语法时,我陷入了表达式。这是我写的BNF符号。
program : expression*
expression: additive_expression
additive_expression : multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
multiplicative_expression : number
| number '*' multiplicative_expression
| number '/' multiplicative_expression
但是我无法理解如何为 ++, --, +=, -=, &&, || etc.
这个运算符编写 BNF 表达式语法。我指的是 C、C++、C#、Python、Java 等语言中的运算符
我知道在使用+, -, *, /
运算符时,语法应该按照BODMAS理论来写。
我想知道的是,写其他运算符的语法是否应该用到什么理论?
我仔细看了 C++ 语言 语法(表达式部分)。但是我看不懂。
<expression> ::= <assignment_expression>
| <assignment_expression> <expression>
<assignment_expression> ::= <logical_or_expression> "=" <assignment_expression>
| <logical_or_expression> "+=" <assignment_expression>
| <logical_or_expression> "-=" <assignment_expression>
| <logical_or_expression> "*=" <assignment_expression>
| <logical_or_expression> "/=" <assignment_expression>
| <logical_or_expression> "%=" <assignment_expression>
| <logical_or_expression> "<<=" <assignment_expression>
| <logical_or_expression> ">>=" <assignment_expression>
| <logical_or_expression> "&=" <assignment_expression>
| <logical_or_expression> "|=" <assignment_expression>
| <logical_or_expression> "^=" <assignment_expression>
| <logical_or_expression>
<constant_expression> ::= <conditional_expression>
<conditional_expression> ::= <logical_or_expression>
<logical_or_expression> ::= <logical_or_expression> "||" <logical_and_expression>
| <logical_and_expression>
<logical_and_expression> ::= <logical_and_expression> "&&" <inclusive_or_expression>
| <inclusive_or_expression>
<inclusive_or_expression> ::= <inclusive_or_expression> "|" <exclusive_or_expression>
| <exclusive_or_expression>
<exclusive_or_expression> ::= <exclusive_or_expression> "^" <and_expression>
| <and_expression>
<and_expression> ::= <and_expression> "&" <equality_expression>
| <equality_expression>
<equality_expression> ::= <equality_expression> "==" <relational_expression>
| <equality_expression> "!=" <relational_expression>
| <relational_expression>
<relational_expression> ::= <relational_expression> ">" <shift_expression>
| <relational_expression> "<" <shift_expression>
| <relational_expression> ">=" <shift_expression>
| <relational_expression> "<=" <shift_expression>
| <shift_expression>
<shift_expression> ::= <shift_expression> ">>" <addictive_expression>
| <shift_expression> "<<" <addictive_expression>
| <addictive_expression>
<addictive_expression> ::= <addictive_expression> "+" <multiplicative_expression>
| <addictive_expression> "-" <multiplicative_expression>
| <multiplicative_expression>
<multiplicative_expression> ::= <multiplicative_expression> "*" <unary_expression>
| <multiplicative_expression> "/" <unary_expression>
| <multiplicative_expression> "%" <unary_expression>
| <unary_expression>
<unary_expression> ::= "++" <unary_expression>
| "--" <unary_expression>
| "+" <unary_expression>
| "-" <unary_expression>
| "!" <unary_expression>
| "~" <unary_expression>
| "size" <unary_expression>
| <postfix_expression>
<postfix_expression> ::= <postfix_expression> "++"
| <postfix_expression> "--"
| <primary_expression>
<primary_expression> ::= <integer_literal>
| <floating_literal>
| <character_literal>
| <string_literal>
| <boolean_literal>
| "(" <expression> ")"
| IDENTIFIER
<integer_literal> ::= INTEGER
<floating_literal> ::= FLOAT
<character_literal> ::= CHARACTER
<string_literal> ::= STRING
<boolean_literal> ::= "true"
| "false"
你能帮我理解一下吗?我在互联网上搜索了很多关于这个的内容。但是我找不到合适的解决方案。
谢谢
我想问题不在于你不知道如何编写 BNF 语法。相反,您不知道应该编写哪种语法。换句话说,如果有人告诉您运算符的优先顺序,您可以毫不费力地写下解析具有该特定优先顺序的运算符的语法。但是您不知道应该使用哪种优先顺序。
不幸的是,没有关于运算符优先级的国际高级委员会,我所知道的任何宗教也没有提供精神参考,包括神圣启发的运算符优先级规则。
对于某些运算符,优先顺序相当明确:例如,采用 BODMAS 是有充分理由的,但主要原因是大多数人已经根据这些规则编写了算术。你当然可以根据群论提出一个看似合理的数学论证,说明为什么乘法优先于加法似乎很自然,但总会有人怀疑这个论证是根据 post facto 来证明 already-made 决定的合理性。尽管如此,使乘法绑定比加法更紧密的论点也适用于 bitwise-and 优先于 bitwise-or,或 boolean-and 优先于 boolean-or。 (尽管我注意到 C 编译器编写者不相信程序员会有那种特殊的直觉,因为如果您在此类表达式中省略多余的括号,大多数现代编译器都会发出警告。)
我认为几乎每个人都会同意的一个优先关系是直观的,即算术运算符优先于比较运算符,比较运算符优先于运算符优先于布尔运算符。大多数程序员会发现一种语言选择将 a > b + 7
解释为意思是“将 a
与 b
进行比较的布尔值加七”。同样,以 (a > 0) || (b > 0)
以外的任何方式解释 a > 0 || b > 0
可能被认为是离谱的。但是其他优先级选择似乎更加随意,并且并非所有语言都使它们相同。 (例如“不等于”和“大于”的相对优先级,或者“异或”和“异或”的相对优先级。
那么语言设计新手应该做什么呢?好吧,首先求助于您自己的直觉,特别是如果您经常使用相关运算符。此外,询问您的朋友、联系人和潜在的语言用户他们的想法。看看其他语言做了什么,但要用批判的眼光看待。在 language-specific 论坛上搜索投诉。很可能是最初的语言设计者做出了一个不幸的(甚至是愚蠢的)选择,现在不能改变这个选择,因为它会破坏太多现有的程序。 (这就是为什么您担心运算符优先级是一件好事:弄错可能会带来严重的未来问题。)
直接实验也有帮助,尤其是对于很少一起使用的运算符。使用运算符定义一个似是而非的表达式,然后根据各种可能的规则将其写出两次(或更多次),省略括号。哪一个看起来更容易理解? (再次招募你的朋友并问他们同样的问题。)
如果最后实在无法决定某对运算符之间的优先顺序是什么,可以考虑另一种解决方案:让这些运算符必须有括号。 (这是 C 编译器抱怨在布尔表达式中省略多余括号的意图。)