我为Pascal创建了一个解析器,而且我遇到了条件语句。
假设我有这段代码:
if ((10 mod 3) = 1) then ...
这是有效的pascal if语句。然而,当我尝试为((10 mod 3) = 1)
表达式提出LL(1)语法时,我崩溃并在括号上刻录。问题是,上述条件可以重写为if (10 mod 3) = 1 then ...
,或者由于运算符优先级为if 10 mod 3 = 1 then ...
我有算术表达式的典型LL(1)语法:
E -> TE'
E' -> ADD_SUB TE' | epsion
T -> FT'
T' -> MUL_DIV FT' | epsilon
F -> 'number' | '(' E ')'
ADD_SUB -> '+' | '-'
MUL_DIV -> '*' | 'div' | 'mod'
但是我无法为整个条件提出LL(1)语法。我想到了类似的东西:
CE -> CT CE'
CE' -> 'or' CT CE' | epsion
CT -> CF CT'
CT' -> 'and' CF CT' | epsilon
CF -> E REL-OP E | '(' E REL-OP E ')' | 'not' E REL-OP E
REL-OP -> '=' | '<' | '<=' | '>' | '>=' | '<>
上面的算术表达式语法中E
为E
。
这不是LL(1),因为CF -> E REL_OP E
和CF -> '(' E REL-OP E ')'
规则包含'('
的第一次碰撞。
如何修复第一次碰撞的任何想法?
答案 0 :(得分:1)
如果我没记错的话,Pascal表达式可以包含比较运算符和布尔运算符,因为它有一个布尔类型。因此,布尔表达式可以出现在表达式可以出现的任何地方,而不仅仅出现在if
语句中。
因此,您需要以expression
为E
(并因此(10 mod 3) = 1
的方式扩展expression
(或编写((10 mod 3) = 1)
) }是expression
),然后if
语句以"if" expression "then"
开头。
如果你真的想为conditional expression
(CE
)创建一个单独的语法类别,那么你必须一直到优先级层次结构的底部,这样你最终会列表以
CE -> CT CE'
CE' -> "or" CT CE' | epsilon
以
结束CF -> 'number' | '(' CE ')'
这些作品中的最后一个将是现有表达式语法的简单复制品,对非终端名称进行一致的更改。但这有很多不必要的重复。