二义性(歧义,Ambiguity)
定义3.7 若文法G对同(至少)一句子产生不止一棵分析树,则称G是二义的。
原因:在产生句子的过程中某些直接推导有多于一种选择
- 一个句子有多于一棵分析树,仅与文法和句子有关,与采用的推导方法无关;
- 造成文法二义的根本原因:文法中缺少对文法符号优先级和结合性的规定。
在计算机编程中,二义性是指一种语法结构可以被解析为多种有不同解释含义的结构的情况。简而言之,就是语法模糊或不确定的情况,把程序员和编译器都搞糊涂。
例如,我们考虑以下简单的语句:
if age > 18 and age < 60 then print "You are an adult"
在这个语句中,我们使用AND运算符将两个布尔表达式相连。然而,这个语句可以解释为两种不同的含义:
- 如果年龄大于18且小于60岁,则打印“你是成年人”。
- 如果年龄大于18,则检查年龄小于60岁时打印“你是成年人”。
这两种解释都是合理的,但却有不同的含义。程序员可以理解它们的区别,但编译器可能会将它们解析为同一个含义。例如,编译器可能认为我们想要的是第二个含义,因为它不知道如何正确理解第一个含义。这就是二义性带来的问题:程序员要表达的含义和编译器所理解的含义不一致。
二义性在编译器中常常导致错误,使得程序无法正确编译或运行。因此,编程语言通常要求对语法和语义进行清晰的规范,以避免出现不明确或模糊的语法结构。语言或编译器的设计师通常会努力确保语法的歧义性最小化,并尽可能提供清晰、简洁和具有明确含义的语法结构。
二义性的消除
消除文法二义的两种方法:
① 改写二义文法为非二义文法;
② 规定二义文法中符号的优先级和结合性,使仅产生一棵分析树。
改写二义文法为非二义文法:
- 新引入的非终结符,限制了每一步直接推导均有唯一选择;
- 最终分析树的形状,仅与文法有关,而与推导方法无关;
- 非终结符的引入,增加了推导步骤(分析树增高);
- 越接近S的文法符号的优先级越低;
- 对于A→αAβ,其右部中,若A在终结符a左边出现(即β中包含a),则终结符a具有左结合性质。
- 改写二义文法的关键步骤:
- 引入一个新的非终结符,增加一个子结构并提高一级优先级;
- 递归非终结符在终结符左边,使该终结符具有左结合性,否则具有右结合性。
为文法符号规定优先级和结合性
- 二义文法的优点:
① 比非二义文法容易理解;
② 分析效率高(分析树低,直接推导步骤少)。修改语言的语法(表现形式被改变)
① 明确给出结束标志
② 给表达式加括号