如何消除后续语法中的含糊之处?
if(this.state.messages['hydra:member'] !== undefined) {
let messages = JSON.parse(JSON.stringify(this.state.messages['hydra:member']));
//use messages here
}
答案 0 :(得分:2)
首先,我们需要找到歧义。
考虑没有F的E的规则;将F更改为f并将其视为终端符号。然后是语法
E -> E * f
E -> f + E
E -> f
含糊不清。考虑f + f * f:
E E
| |
+-------+--+ +-+-+
| | | | | |
E * f f + E
+-+-+ |
| | | +-+-+
f + E E * f
| |
f f
我们可以通过强制*或+优先来解决这种歧义。通常,*优先于操作顺序,但这完全是任意的。
E -> f + E | A
A -> A * f | f
现在,字符串f + f * f只有一个解析:
E
|
+-+-+
| | |
f + E
|
A
|
+-+-+
A * f
|
f
现在,考虑使用F而不是f:
的原始语法E -> F + E | A
A -> A * F | F
F -> F - F | id
这是不明确的?它是。考虑字符串id - id - id。
E E
| |
A A
| |
F F
| |
+-----+----+----+ +----+----+----+
| | | | | |
F - F F - F
| | | |
+-+-+ id id +-+-+
F - F F - F
| | | |
id id id id
这里的含糊之处在于 - 可以是左关联的或右关联的。我们可以选择与+:
相同的约定E -> F + E | A
A -> A * F | F
F -> id - F | id
现在,我们只有一个解析:
E
|
A
|
F
|
+----+----+----+
| | |
id - F
|
+--+-+
| | |
id - F
|
id
现在,这个语法是不明确的?事实并非如此。
s完全具有#(+)+ s,#(*)* s和#( - ) - s可以理所当然(如果s中不存在,则数字可以为零)。那个E - > A,A - > F和F - > id必须正好使用一次,如下所示:
如果E - >; A永远不会被使用,任何派生的字符串仍然会有E,一个非终结符号,因此不会是该语言中的字符串(如果没有使用E - > A至少一次就不生成任何内容)。此外,在使用E之前可以生成的每个字符串 - > A中最多只有一个E(你从一个E开始,唯一的另一个产品保留一个E)所以永远不可能使用E - >不止一次。所以E - > A仅对所有派生字符串使用一次。对于A - >演示以相同的方式工作。 F和F - >标识。
那个E - > F + E,A - > A * F和F - > id-F分别用于#(+),#(*)和#( - )次,这是因为这些是唯一引入各自符号并且每个引入一个实例的产品。
如果你考虑我们得到的语法的子语法,我们可以证明它们是明确的如下:
F -> id - F | id
(id - )*id
这是一个明确的语法。 (id - )^kid
的唯一推导是使用F -> id - F
k次,然后恰好使用F -> id
一次。
A -> A * F | F
我们已经看到F对于它识别的语言是明确的。通过相同的论证,这是语言F( * F)*
的明确语法。 F( * F)^k
的推导需要使用A -> A * F
恰好k次,然后使用A -> F
。因为从F
生成的语言是明确的,并且因为A
的语言明确地使用*来分隔F的实例,而不是由F生成的符号,语法
A -> A * F | F
F -> id - F | id
也是毫不含糊的。要完成参数,请将相同的逻辑应用于起始符号E的语法生成(F +)* A.