提问人:Witness Protection ID 44583292 提问时间:11/2/2023 最后编辑:LesWitness Protection ID 44583292 更新时间:11/3/2023 访问量:126
在不回溯的情况下解析 C 赋值表达式的诀窍是什么?
What is the trick to parsing a C assignment-expression with no backtracking?
问:
自上而下解析 C 必须在 a 和 a 之间进行选择。(不幸的是,很复杂)BNF 是:assignment-expression
conditional-expression
unary-expression
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
<conditional-expression> ::= <logical-or-expression>
| <logical-or-expression> ? <expression> : <conditional-expression>
<logical-or-expression> ::= <logical-and-expression>
| <logical-or-expression> || <logical-and-expression>
<logical-and-expression> ::= <inclusive-or-expression>
| <logical-and-expression> && <inclusive-or-expression>
<inclusive-or-expression> ::= <exclusive-or-expression>
| <inclusive-or-expression> '|' <exclusive-or-expression>
<exclusive-or-expression> ::= <and-expression>
| <exclusive-or-expression> ^ <and-expression>
<and-expression> ::= <equality-expression>
| <and-expression> & <equality-expression>
<equality-expression> ::= <relational-expression>
| <equality-expression> == <relational-expression>
| <equality-expression> != <relational-expression>
<relational-expression> ::= <shift-expression>
| <relational-expression> < <shift-expression>
| <relational-expression> > <shift-expression>
| <relational-expression> <= <shift-expression>
| <relational-expression> >= <shift-expression>
<shift-expression> ::= <additive-expression>
| <shift-expression> << <additive-expression>
| <shift-expression> >> <additive-expression>
<additive-expression> ::= <multiplicative-expression>
| <additive-expression> + <multiplicative-expression>
| <additive-expression> - <multiplicative-expression>
<multiplicative-expression> ::= <cast-expression>
| <multiplicative-expression> * <cast-expression>
| <multiplicative-expression> / <cast-expression>
| <multiplicative-expression> % <cast-expression>
<cast-expression> ::= <unary-expression>
| ( <type-name> ) <cast-expression>
<unary-expression> ::= <postfix-expression>
| ++ <unary-expression>
| -- <unary-expression>
| <unary-operator> <cast-expression>
| sizeof <unary-expression>
| sizeof <type-name>
<postfix-expression> ::= <primary-expression>
| <postfix-expression> [ <expression> ]
| <postfix-expression> ( {<assignment-expression>}* )
| <postfix-expression> . <identifier>
| <postfix-expression> -> <identifier>
| <postfix-expression> ++
| <postfix-expression> --
<primary-expression> ::= <identifier>
| <constant>
| <string>
| ( <expression> )
请注意,a 满足该规则。unary-expression
cast-expression
如果输入是,并且解析器首先尝试分支,则输入只需停在 即可满足规则。解析器必须回溯并考虑分支才能发现该部分。X=3
conditional-expression
primary-expression
X
unary-expression assignment-operator assignment-expression
=3
如果输入是,并且解析器首先尝试分支,则永远不会找到,并且解析器必须回溯并考虑分支以发现规则。X==Y
unary-expression
assignment-operator
conditional-expression
equality-expression
我不明白如何在任何地方左分解 BNF 以避免回溯。递归和回溯是不可避免的吗?还是有诀窍?
编辑:为了回应要求简化语法的评论,下面将演示 vs。 问题,但只是为了证明简化的语法如何需要回溯,对于那些不想摸索完整语法的人来说。为避免在这种简化的语法中回溯而进行的任何修复都可能无法使用完整语法。X=3
X==Y
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <unary-expression>
<conditional-expression> ::= <unary-expression> == <unary-expression>
<unary-expression> ::= <identifier>
<assignment_operator> ::= '='
如果输入是,并且解析器首先查找,则找不到,因此解析器必须回溯,而输入则无需回溯即可工作。X=3
conditional-expression
==
X==Y
如果输入是,并且解析首先查找,则输入是可以接受的,而输入将需要回溯才能匹配。X=3
unary-expression
X==Y
conditional-expression
答: 暂无答案
上一个:减少/减少冲突野牛语法
评论
=
=
C
X
X
primary-expression
conditional-expression
X
conditional-expression
=
unary-expression
assignment-expression
assignment-operator
=
assignment-expression
compound-statement
external-declaration
parameter-declaration
specifier-qualifier