类C语言词法分析器的设计--c++实现

 一、词法分析器简介
       词法分析过过程,即从左至右扫描输入串,并将其转化为有特定含义单词符号(token,相当于DFA中的终结符)。同时,删除空白符(whitespace,包括空格,'/t','/r','/n')。其中单词符号种类包括:标识符,关键字,常数(本例中包括int,real,字符串,char类型),还有{,},[,],(,),;,*/-+等特定符号。
      词法分析器相当于语法分析器的一个子函数。当语法分析器为了分析一个句子时,就需要调用词法分析器来获取一个单词,按需索取,并不是我原先所理解的那样,先由词法分析器把源文件一遍统统分析完,再全部交与语法分析器。就像吃饭一样,饿了才做,而不是一次都做出来,以后慢慢吃,这样可以避免浪费,不是吗?
         具体流程图如下:


二、DFA(关键部分)
    图就不画了,现在没什么时间,弄这个耗了我三天了,得准备复试了。
    DFA的实现是采用switch-case的控制流方式,case结点都为DFA的非终结态,终态直接返回。当然case中又有if-else控制语句。
    Token的获取采用“地主-长工”模式(自创的,待以后对GOF的模式熟悉后再为其正名),即GetNextToken()作为lex对外接口,负责返回一个Token,这是个体面活,相当于一个地主。然而,其内部,长达250多行的DFA转化工作由它的长工ProceedChar()来完成。地主每次从输入串中获取一个char,然后交给长工,然后长工根据以前记录的状态以及后文(超前搜索,主要用于/**/,<=,==,>=,!=等两个以上字符组合的识别中),来判断出这个Token何时结束,是哪一种类(id)。

三、实现之类图
Clex:词法分析器
symTalbe:符号表,insert(Token  tk)操作先判断符号表中是否已先存在tk,若是则无操作
Token:单词符号,text属性为表示该单词符号的字符串,tid为其属性


四、程序结果
注:不支持头文件的识别,数据类型只有int,real,char。其余和C语言类似
输入测试程序代码:
int main()
{
    int a=3;  /*dddd
    dddd*/
    real b=1.2;
    char c='c';
    write("string");
}
结果:


五、开发笔记一二

1.编译运行时,测试文件应放在工程目录下,生成可执行文件后,才可放在可执行文件目录下。

2.编程时最好一句一行,以便调试。
3. ios 类的 get (), unget (), peek() 对单个输入字符的读取,退回输入流,测试方便了超前搜索的实现。 但要主义当srcfile.get(c)返回假,即文件读取完毕时,c的值是没有改变的,所以此时自己设置其c=NULL,可方便后文对文件结束的判断。

六、关键代码( 欢迎下载源文件并指导)
见过250多行的函数吗?反正我是第一次写这么长的,调试过程是很辛苦滴:)
bool Clex::GetNextToken(Token &  tok)
{
    StripBC();
    tk.text.clear();
    tk.tid
=syn_start;
    state
=dfa_start;

    
char c;
    
//c为空时表示文件读取完毕,但此时必须让ProceedChar也知道,故用do-while
    do
    
{
        
if!srcfile.get(c))
            c
=NULL;
    }
while((state=ProceedChar(c))<dfa_INTERVAL  && c);
    
    
if( tk.tid==syn_id && !isKey() ) //判断标识符是否为关键字,若不是插入符号表
        symtbl.Insert(tk);

    tok
=tk;
    
if( NULL==c) return false;    //文件读取完毕,返回false
    return true;                        //文件尚未读完
}


// DFA
DFA_state Clex::ProceedChar( char  ch)
{
    
switch( state )
    
{
        
case dfa_start:
        
if( isalpha(ch) )
        
{
            tk.text
+=ch;
            
return dfa_inid;
        }
    //come to be a indentifer
        else if( isdigit(ch) )
        
{
            tk.text
+=ch;
            
return dfa_inint;
        }

        
else if';'==ch )
        
{
            tk.text
=ch;
            tk.tid
=syn_semi;
            
return dfa_semi;
        }

        
else if'('==ch )
        
{
            tk.text
=ch;
            tk.tid
=syn_lbrace;
            
return dfa_lbrace;
        }

        
else if')'==
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值