//////////////////////////////////////////////////////////////////////////// if (isdigit(ch)) { value[i++] = ch;
//如果第一个数字是0,则有可能是INT10的0、INT8或INT16 if (ch == '0') {
ch = from_file.get();
if ((ch >= '0' && ch < '8') || ch == 'x' || ch == 'X') { //如果0后面紧跟着数字0-8,则为INT8 if (isdigit(ch)) {
while (ch >= '0' && ch < '8') { value[i++] = ch; ch = from_file.get(); }
from_file.unget();
return new Token(INT8, value, value); }
value[i++] = ch; //到这一步的都是INT16 ch = from_file.get();
while (isdigit(ch) || (ch >= 'a' && ch <= 'f')) { value[i++] = ch;
//TODO:这里没有解决0xrtr的问题 ch = from_file.get(); }
from_file.unget();
return new Token(INT16, value, value);
} else {//0后面的不为0-7的digit或x或X等 8或16进制特征字符,则为10进制的0,回退一个字符
from_file.unget();
return new Token(INT10, value, value); } }
//能到这一步的都是INT10,且不为0打头 ch = from_file.get(); while (isdigit(ch)) { value[i++] = ch; ch = from_file.get(); }
from_file.unget();
return new Token(INT10, value, value); }
//////////////////////////////////// value[i++] = ch;
以
下
为
运
算
符
的
检
测
////////////////////////////////////////////////////////////////////////////
switch (ch) {
case '+': return new Token(ADD, value, \); case '-': return new Token(MINUS, value, \); case '*': return new Token(MUL, value, \); case '/': return new Token(DIC, value, \); case '>': return new Token(MORE, value, \); case '<': return new Token(LESS, value, \); case '=': return new Token(EQU, value, \); case '(': return new Token(LBRAC,value, \); case ')': return new Token(RBRAC, value, \); case ';': return new Token(COMMA, value, \); default:ErrorHandle(from_file); break; }
return new Token(DEFAULT, NONE_OF_VALUE, NONE_OF_VALUE); }
实验结果:
实验中遇到的问题及其解决:
1、保留字的检测问题:
一开始的时候我的想法是遇到if、while、do、then等单词的首字母时即开始划分状态,后来发现这样子判断的分支会特别多,而且效率不是很高,对保留字集合的扩展支持的也不是很好。后来我发现保留字存在于标识符的子集,所以为什么不先判断标识符然后再判断是不是保留字呢?后来我就照着这个思路成功实现了功能。
2、关于0为首位的数字是int8、int10和int16的判断问题:
当读入的第一个字符为0时,可能为int8、可能是int10的0也可能是int16的开头,当下一个字符是0~7时,开始进行int8的匹配;当下一个字符是x或X时,开始进行int16的匹配;当下一个字符为其他字符时,说明这是一个十进制的0(此时还需进行一字节的回退)
3、关于回退的问题:
有些时候需要进行回退,否则不能正常的进行完整个分析过程,需要进行回退的场合为: (1) 匹配标识符(或保留字时),向后逐字读取的时候当下一个不是字母或数字的时候需要
将读取的字符回退,才能继续向下进行; (2) 判断为int10的0的时候需要一步回退:
else {//0后面的不为0-7的digit或x或X等 8或16进制特征字符,则为10进制的0,回退一个字符
from_file.unget();
return new Token(INT10, value, value); }
(3) 判断数字的时候到最后一个不为数字的都需要回退。
实验二 自顶向下的语法分析—递归子程
改写后的产生式集合:
S -> id = E; S -> if C then S; S -> while C do S; C -> E > E; C -> E <= E; E -> T (+ T) *; E -> T (- T) *; T -> F (* F) *; T -> F (/ F) *; F -> (E); F -> id; F -> int8; F -> int10; F -> int16;
化简后的语法图:
+ET*TF
序法
-ET /TF
递归子程序算法
int ProcedureS(ifstream& from_file) { Indent();
cout<<\< indentation += 4;//子程序开始 Indent(); Token* token = TokenScan(from_file); if (token->type == IF) { cout< token = TokenScan(from_file); Indent(); if (token->type == THEN) { cout< } else if (token->type == WHILE) { cout< token = TokenScan(from_file); Indent(); if (token->type == DO) { cout< } else if (token->type == IDN) { cout<<\< cout< indentation -= 4;//子程序结束 return 0; 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库北京工业大学 编译原理 实验报告(2)在线全文阅读。
相关推荐: