代码下载: git clone git://git.code.sf.net/p/redy/code redy-code这一章的内容有:
关键字的识别
(1)简介
在Redy中,总共有这么一些关键字:
在前面,我们是把关键字和识别与变量的识别结合再一起来,这样做是因为为关键字构造状态机是一件很烦锁的事情,如果要构造一个能成功识别上面关键字的状态机,至少需要100多个状态,无论是编写,绘图,还是维护都是一件费脑力与体力的活,所以,我们也关键字的识别与变量识别结合在一起,当词法识别系统识别到一个变量的词文时,我们再来对判断该词文是否真的是变量,还是关键字。
- 'class' 'attr' 'end' 'inhrit' 'vfunc' 'func'
- 'import' 'as' 'to' 'from'
- 'break' 'continue' 'for' 'while' 'do' 'in'
- 'if' 'elif' 'else' 'then'
- 'return' 'and' 'or' 'not'
- 'print' 'try' 'catch' 'finally
第一步:我们用一个结构体来表示关键字:
- struct keyword
- {
- char* k_name;
- int k_token;
- };
其中成员k_name表示该关键字的名称,k_token用于表示该关键字的词文类型,用于后面的语法分析。
第二步:用一个数组来保存这些关键字,关键字按字典顺序排列。
- struct keyword key_words[]=
- {
- {"and",TOKEN_AND},
- {"as",TOKEN_AS},
- {"attr",TOKEN_ATTR},
- {"break",TOKEN_BREAK},
- {"catch",TOKEN_CATCH},
- {"class",TOKEN_CLASS},
- {"continue",TOKEN_CONTIUNE},
- {"do",TOKEN_DO},
- {"elif",TOKEN_ELIF},
- {"else",TOKEN_ELSE},
- {"end",TOKEN_END},
- {"finally",TOKEN_FINALLY},
- {"for",TOKEN_FOR},
- {"from",TOKEN_FROM},
- {"func",TOKEN_FUNC},
- {"if",TOKEN_IF},
- {"import",TOKEN_IMPORT},
- {"in",TOKEN_IN},
- {"inhrit",TOKEN_INHRIT},
- {"not",TOKEN_NOT},
- {"or",TOKEN_OR},
- {"print",TOKEN_PRINT},
- {"return",TOKEN_RETURN},
- {"then",TOKEN_THEN},
- {"to",TOKEN_TO},
- {"try",TOKEN_TRY},
- {"vfunc",TOKEN_VFUNC},
- {"while",TOKEN_WHILE},
- };
第三步:因为我们前面已经对关键字按照字典顺序排序,这样做的目的为,我们可以使用二分查找算法来加速整个查找的过程。我们这里用一个函数来实现查找,如果参数symbol是关键字,则返回关键字的类型,否则说明该词文是一个变量,则返加TOKEN_ID。
- int symbol_type(char* symbol)
- {
- int begin=0;
- int end=KEYWORD_NUM-1;
- int middle;
- while(begin<=end) /*采用二分查找算法*/
- {
- middle=(begin+end)/2;
- int ret=strcmp(symbol,key_words[middle].k_name);
- printf("cmp %s ,%s =%d\n",key_words[middle].k_name,symbol,ret);
- if(ret<0)
- {
- end=middle-1;
- }
- else if(ret >0)
- {
- begin=middle+1;
- }
- else
- {
- return key_words[middle].k_token;
- }
- }
- return TOKEN_ID;
- }
第四步:写一个小程序测试程序来判断前面的程序是否工作正常。
- int main()
- {
- char buf[1024];
- printf("input __quit__ exit\n");
- printf("input:\n");
- scanf("%s",buf);
- while(strcmp(buf,"__quit__")!=0)
- {
- int token=symbol_type(buf);
- printf("it's %s\n",token_info[token]);
- printf("input:\n");
- scanf("%s",buf);
- }
- return 0;
- }
运行结果:
大家在tutorial/lexical/keywords下面找到源程序。