您的位置:首页 > 其它

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

2014-01-29 13:36 337 查看
参考文章
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()。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: