<u>数字不允许作为首字符出现,这样就可以轻易的区别开标识符和数字了</u>
编译原理中的词法分析问题,程序语言的分析分词法和语法两部分。词法分析主要用的是正规文法,即三型文法,主要采用正则表达式分析。正则文法分析器的特点是不回溯(编译器在解析程序时,读到单词的第一个字符就能知道当前这个单词属于哪一类,如果是数字,则可以直接跳入数字处理的模块,若是字符则按变量名来处理)。
如果一个变量以数字开头,那么分析器就必须在遇到第一个或第二个英文字符的时候回溯来确定是否是数字、变量名还是词法错误,这时候就变成了二型文法。二型文法分析器的好处是支持回溯和递归语法(所以语法分析是靠它的),缺点是状态机相比正则文法状态大大增加,而且代码写起来更困难。
考虑到词法分析部分只是用来断字,我们实在是没有为了支持变量名以数字开头这么一个小功能而让整个词法分析部分用二型文法写。最后大家都默认了变量要避免用数字开头。
扩展:四种文法
乔姆斯基把文法分成四种类型,即0型、1型、2型和3型。
0型文法
设G=(VN,VT,P,S),如果它的每个产生式α→β是这样一种结构:α∈(VN∪VT)且至少含有一个非终结符,而 β∈(VN∪VT),则G是一个0型文法。0型文法也称短语文法。一个非常重要的理论结果是:0型文法的能力相当于图灵机(Turing)。或者说,任 何0型文语言都是递归可枚举的,反之,递归可枚举集必定是一个0型语言。0型文法是这几类文法中,限制最少的一个,所以我们在试题中见到的,至少是0型文 法。
1型文法
1型文法也叫上下文有关文法,此文法对应于线性有界自动机。它是在0型文法的基础上每一个α→β,都有|β|>=|α|。这里的|β|表示的是β的长度。
注意:虽然要求|β|>=|α|,但有一特例:α→ε也满足1型文法。
如有A->Ba则|β|=2,|α|=1符合1型文法要求。反之,如aA->a,则不符合1型文法。
2型文法
2型文法也叫上下文无关文法,它对应于下推自动机。2型文法是在1型文法的基础上,再满足:每一个α→β都有α是非终结符。如A->Ba,符合2型文法要求。
如Ab->Bab虽然符合1型文法要求,但不符合2型文法要求,因为其α=Ab,而Ab不是一个非终结符。
3型文法
3型文法也叫正规文法,它对应于有限状态自动机。它是在2型文法的基础上满足:A→α|αB(右线性)或A→α|Bα(左线性)。
如有:A->a,A->aB,B->a,B->cB,则符合3型文法的要求。但如果推导 为:A->ab,A->aB,B->a,B->cB或推导 为:A->a,A->Ba,B->a,B->cB则不符合3型方法的要求了。具体的说,例子 A->ab,A->aB,B->a,B->cB中的A->ab不符合3型文法的定义,如果把后面的ab,改成“一个非终结 符+一个终结符”的形式(即为aB)就对了。例子A->a,A->Ba,B->a,B->cB中如果把B->cB改为 B->Bc的形式就对了,因为A→α|αB(右线性)和A→α|Bα(左线性)两套规则不能同时出现在一个语法中,只能完全满足其中的一个,才能算 3型文法。
注:上面例子中的大写字母表示的是非终结符,而小写字母表示的是终结符。