开源编译器学习笔记02(VC6 词法扫描器 ——GetToken)——2014_1_29


参考文章

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()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值