开源编译器学习笔记02(VC6 词法扫描器 ——GetToken)——2014_1_29
2014-01-29 13:36
337 查看
参考文章
http://www.zengl.com/html/genlanmu/zenglbianchengyuyan/article-2.html
***********************************************************
词法分析函数();
case START:
START处理函数();
break;
case INID:
INID处理函数();
break;
case INNUM:
INNUM处理函数();
break;
可以看出,词法分析函数分成来 三个部分,
***************************************************
START处理函数();
if(ch==' ' || ch=='t' || ch=='n')
//如果是换行回车之类的就跳过。
continue;
else if(isalpha(ch)) //判断读取的字符是否是英文字母。
{
state=INID; //如果是字母,我们就将state状态机设置为INID 。
makeTokenStr(ch); //然后将读取出来的ch字符通过函数makeTokenStr加入到TokenString动态字符串里
}
else if(isdigit(ch)) //判断读取的字符是否是数字
{
state=INNUM; //如果是数字,我们就将state状态机设置为INNUM 。
makeTokenStr(ch); //然后将读取出来的ch字符通过函数makeTokenStr加入到TokenString动态字符串里
}
else
{
处理ch函数();
}//switch(ch)
makeTokenStr(ch);
}
******************************************************
INID处理函数();
if(isalpha(ch)) //在INID状态下,一直读取字符,直到该字符不是字母为止,并将读取的字母通过makeTokenStr构成完整的标示符。
makeTokenStr(ch);
else
{
state = DOWN;
token = ID; //将token设为ID表示读取到了一个标示符。ID即identifier 英文缩写。
ungetchar(); //因为多读取了一个非字母的字符,所以用ungetchar函数来回退一个字符,供下一次扫描使用。
}
********************************************************
INNUM处理函数();
if(isdigit(ch)) //在INNUM状态下,一直读取字符,直到该字符不是数字为止,并将读取的单个数字通过makeTokenStr构成完整的数值。
makeTokenStr(ch);
else
{
state = DOWN;
token = NUM; //将token设为NUM表示读取到了一个数字。
ungetchar();
}
************************************************************
其实词法扫描器就是循环读取文件里的字符。
并通过读取到的首字符判断是哪种类型的token,如果是字母,说明当前读到的部分是标示符,就将state状 态机由START开始读取的状态转为INID(在identifier的状态即处于标示符的读取状态),在INID的switch case里将后面的连续的字母和首字母一起构成一个完整的标示符,并将这些连续的字母存放到TokenString动态字符串里,这样就找到了一个 token了。
其他的数字,运算符之类的Token也是同理查找。
************************************************************
enum TOKENTYPE{
ID,NUM,PLUS,MINIS,TIMES,DIVIDE,ASSIGN,ENDFILE,ERROR
};
enum STATES{
START,INID,INNUM,DOWN
};
***********************************************************
处理ch函数();
state = DOWN; //如果字符是‘+’号就将state状态机设为DOWN,这样就可以结束循环,并把token设为PLUS枚举值,表示找到加号运算符。
token = PLUS;
break;
case '-':
state = DOWN; //和上面同理
token = MINIS;
break;
case '*':
state = DOWN; //和上面同理
token = TIMES;
break;
case '/':
state = DOWN; //和上面同理
token = DIVIDE;
break;
case '=':
state = DOWN; //和上面同理
token = ASSIGN;
break;
case EOF:
state = DOWN; //EOF字符表示读取到了文件的结尾,则返回ENDFILE的token,在外层main函数的主循环就会结束扫描。
token = ENDFILE;
break;
default:
state = DOWN; //其他情况下表示读取到了未定义的token,那么就返回ERROR。
token = ERROR;
break;
*******************************************************************************
其它的函数刚开始都可以理解成黑盒子,即直接使用,其具体实现可以以后再理解,这样不影响编译器学习,也不至于负担太重。
getNextchar();
isalpha();
isdigit();
makeTokenStr();
ungetchar()。
http://www.zengl.com/html/genlanmu/zenglbianchengyuyan/article-2.html
enum TOKENTYPE getToken() { enum STATES state = START;//设置起始状态为START enum TOKENTYPE token; while(state!=DOWN)//当state状态为DOWN时,表示找到一个变量或者别的token(一般变量,加减符号,数字等每个扫描出来的元素都称作token) { char ch = getNextchar(); //打开一个文件,并从中读取一个字符 switch(state) { 词法分析函数(); }//switch(state) }//while(state!=DOWN) return token; }//enum TOKENTYPE getToken()
***********************************************************
词法分析函数();
case START:
START处理函数();
break;
case INID:
INID处理函数();
break;
case INNUM:
INNUM处理函数();
break;
可以看出,词法分析函数分成来 三个部分,
***************************************************
START处理函数();
if(ch==' ' || ch=='t' || ch=='n')
//如果是换行回车之类的就跳过。
continue;
else if(isalpha(ch)) //判断读取的字符是否是英文字母。
{
state=INID; //如果是字母,我们就将state状态机设置为INID 。
makeTokenStr(ch); //然后将读取出来的ch字符通过函数makeTokenStr加入到TokenString动态字符串里
}
else if(isdigit(ch)) //判断读取的字符是否是数字
{
state=INNUM; //如果是数字,我们就将state状态机设置为INNUM 。
makeTokenStr(ch); //然后将读取出来的ch字符通过函数makeTokenStr加入到TokenString动态字符串里
}
else
{
处理ch函数();
}//switch(ch)
makeTokenStr(ch);
}
******************************************************
INID处理函数();
if(isalpha(ch)) //在INID状态下,一直读取字符,直到该字符不是字母为止,并将读取的字母通过makeTokenStr构成完整的标示符。
makeTokenStr(ch);
else
{
state = DOWN;
token = ID; //将token设为ID表示读取到了一个标示符。ID即identifier 英文缩写。
ungetchar(); //因为多读取了一个非字母的字符,所以用ungetchar函数来回退一个字符,供下一次扫描使用。
}
********************************************************
INNUM处理函数();
if(isdigit(ch)) //在INNUM状态下,一直读取字符,直到该字符不是数字为止,并将读取的单个数字通过makeTokenStr构成完整的数值。
makeTokenStr(ch);
else
{
state = DOWN;
token = NUM; //将token设为NUM表示读取到了一个数字。
ungetchar();
}
************************************************************
其实词法扫描器就是循环读取文件里的字符。
并通过读取到的首字符判断是哪种类型的token,如果是字母,说明当前读到的部分是标示符,就将state状 态机由START开始读取的状态转为INID(在identifier的状态即处于标示符的读取状态),在INID的switch case里将后面的连续的字母和首字母一起构成一个完整的标示符,并将这些连续的字母存放到TokenString动态字符串里,这样就找到了一个 token了。
其他的数字,运算符之类的Token也是同理查找。
************************************************************
enum TOKENTYPE{
ID,NUM,PLUS,MINIS,TIMES,DIVIDE,ASSIGN,ENDFILE,ERROR
};
enum STATES{
START,INID,INNUM,DOWN
};
***********************************************************
处理ch函数();
state = DOWN; //如果字符是‘+’号就将state状态机设为DOWN,这样就可以结束循环,并把token设为PLUS枚举值,表示找到加号运算符。
token = PLUS;
break;
case '-':
state = DOWN; //和上面同理
token = MINIS;
break;
case '*':
state = DOWN; //和上面同理
token = TIMES;
break;
case '/':
state = DOWN; //和上面同理
token = DIVIDE;
break;
case '=':
state = DOWN; //和上面同理
token = ASSIGN;
break;
case EOF:
state = DOWN; //EOF字符表示读取到了文件的结尾,则返回ENDFILE的token,在外层main函数的主循环就会结束扫描。
token = ENDFILE;
break;
default:
state = DOWN; //其他情况下表示读取到了未定义的token,那么就返回ERROR。
token = ERROR;
break;
*******************************************************************************
其它的函数刚开始都可以理解成黑盒子,即直接使用,其具体实现可以以后再理解,这样不影响编译器学习,也不至于负担太重。
getNextchar();
isalpha();
isdigit();
makeTokenStr();
ungetchar()。
相关文章推荐
- 开源编译器学习笔记03(VC6 词法扫描器 ——动态内存先放一边)——2014_1_30
- 开源编译器学习笔记01(VC6 词法扫描器)——2014_1_28
- 开源编译器学习笔记06(VC6 语法分析器——见面语法树状态机之start)——2014_2_2
- 开源编译器学习笔记05(VC6 语法分析器——见面语法树状态机)——2014_2_1
- 开源编译器学习笔记04(VC6 动态节点数组——AddNode)——2014_1_31
- 编译原理学习笔记13——(没有plan b的斧头帮—— LL分析法)——2014_1_29
- 编译原理学习笔记02——(对最基本文法的理解)——2014_1_12
- 2014-02学习笔记
- 02-Swift学习笔记-元组类型
- Java学习笔记29 内部类(Inner Cla…
- 我的QT学习笔记-02-QTimerEvent类定时器
- JAVA高级视频02_IO输入与输出 06 PipedInputStream和PipedOutPutStream 学习笔记
- xamarin 学习笔记02- IOS Simulator for windows 安装
- Flex学习笔记_02 Hello Flex
- thinkPHP+MySQL学习笔记-2014-10
- android设计模式学习笔记02--组合模式
- 学习笔记-多项式的加减乘数及微分的C++实现15/11/02
- Spring 学习笔记02
- (原创)c#学习笔记08--面向对象编程简介01--面向对象编程的含义01--对象的含义02--方法
- 西部开源学习笔记《unit 6》