回 帖 发 新 帖 刷新版面

主题:[原创]c语言词法分析器

我所编写的是吉林大学一年级上学期的课程设计——词法分析器,这是我和同学努力的结果,希望对大家有用,源码运行环境win7,用codeblocks编译

回复列表 (共8个回复)

沙发

不错的啊  mark下

板凳

如果文件里面出现了“/*”却没有出现“*/”,似乎会进入死循环。(我没有实际运行,只是随便说说)
词法分析器一般要求正则文法。而对于正则文法,理论上可以不必倒退,一次性解析完毕。也就是说,像fseek这样的函数其实是没有必要使用的,制作一个有穷自动机,挨个的fgetc即可。当然更好的做法是一次读取大量数据放到一个数组中,然后一点一点的解析,这样可以减少函数调用次数,速度更快。

3 楼

谢谢评论,不过我们说编写的这个程序的思想是逐个逐个的“词”来读入,既需要判断不同的“词”,这样一来就会多读入一个用来判断,所以在某些地方有必要加入fseek函数来调整文件指针,对于你所讲到的/*我想您是看错了,不过我又更新了附件,您可以在看看,请您多指正批评

4 楼

楼主的研究精神 值得我们高度学习。

[quote] 
词法分析器一般要求正则文法。而对于正则文法,理论上可以不必倒退,一次性解析完毕。也就是说,像fseek这样的函数其实是没有必要使用的,制作一个有穷自动机,挨个的fgetc即可。当然更好的做法是一次读取大量数据放到一个数组中,然后一点一点的解析,这样可以减少函数调用次数,速度更快。[/quote]

表示赞同。可以定义这样的全局变量char buffer[2][BUF_SIZE]或char buffer[BUF_SIZE]这样的全局变量。然后定义PUTS() ,GETC(),UNGETC(c)这几个宏来分别实现把数据缓存到buffer,从buffer获取1个字符,把字符c压回buffer(有时候需要超前搜索).

楼主的代码还有很多方面莫有实现,如 L'a' , L"abc", 0x123efw(16进制数), *(乘号和指针取对象), 01248(8进制), += -=等(这些复合赋值符), != == &&(等等,很多符号) 。。。
感觉有很多方面还要改善,就简单的说说整数和浮点数.0开头的8进制只允许0-7这几个字符, 0x开头的16进制只允许0-9a-fA-F这些字符。整数后面可以跟U,L这样的后缀,如124L,123U,123LLU等。像这样的浮点数都是合法的:1.0,1.,1.0F,.4f,1.E-4.

在词法分析器发现上面的错误时,应该停止工作,给出错误信息。

5 楼

楼主,再给您一些建议:

现在,一般的词法分析器都是用 有限自动机(FA) 来自动分析的。
比如说分析 整数(不考虑整数后面的后缀UL等)。 
  最开始什么都没输入的时候 我们成为 状态0(STAT_START)
    如果输入字符0, 进入 状态1
    如果输入字符1-9,进入 状态2
  在状态1的时候,  如果输入1-7, 进入 状态3
           如果输入x|X, 进入 状态4
  在状态2的时候, 如果输入 0-9, 进入 状态2(循环接受字符0-9)
                  如果输入 空白字符, 进入 状态5(终态) <<<-
  在状态3的时候, 如果输入 0-7, 进入 状态3(循环接受字符0-7)
                  如果输入 空白字符, 进入 状态6(终态) <<<-
  在状态4的时候, 如果输入 0-9a-fA-F, 进入状态4(循环)
                  如果输入 空白字符, 进入 状态7(终态) <<<-
  
  如果不是上面的输入情况,应该停止工作,给出错误信息。
  不同的终态表示不同的情况,如 运算符, 括号, 标识, 8进制数, 10进制数等。

  这样,我们首先把所有字符分类,映射成像下面的几类;
  digit_8:[0-7] digit_10:[0-9] digit_16:[a-fA-F] eE:[eE] xX:[xX] zero:[0]
  fF:[Ff]  lL:[Ll] letter:[_a-zA-Z] 等等。一般像+-!%*()这样的符号都单独分类。

  然后把 语言里面的各种词汇用正则式表达出来,保存到某个文件如in.txt
  integer_base_8      0{digit_8}*         
  integer_base_16     0[xX]{digit_16}+
  identifier          {letter}{letter | digit_10}*    
  。。。。

  然后用脚本语言或者c语言写一个程序,把in.txt里面的类容转换成 非确定性有限自动机(NFA), 然后把NFA转换成DFA,在把DFA优化。运行程序然后输出 某个语言的词汇的 状态表。这就说所谓的 词法分析器自动生成器 的原理。


  有了上面的 状态表,我们可以把它 复制粘贴 到我们真正的 C语言源代码中。后面的工作非常简单了。这样做是有好处的。如果哪天,您还想写个Python的词法分析器,只要把in.txt里面的内容改变一下,就很容易得到Python 的词法分析状态表。

  还有,保留字的识别问题,可以把它们全部定义为某个状态,那么最终得到的状态表非常大,那么至少有200个状态,如果 我们把字符分为20类,那么这个表将有200*20,很大吧??也可以把保留字和标识同等对待,然后再识别。上次在哪里看到过一句话,好像有人证明有可能可以设计一个 完美的哈希函数,把所有关键字映射到某个表中。如果您能设计出一个好的哈希函数,分析速度应该会提速不少。

  当然,状态表也可以有人工来填写,不过那可是一个巨大的工程哦。。

  

6 楼

实话说我只是一个刚刚接触编程的大一的菜鸟,不过在+=,-=等地方我们做了处理啊,我有很多东东都不会,非常感谢您给的建议,可我还是不明白您的评论,您能给出具体代码么,非常感谢

7 楼

我们的这个词法分析器是在比较短的时间完成的,并没有做报错的功能,只是在思想上和其他编程爱好者的词法分析器不同
[em2]

8 楼

http://bbs.pfan.cn/post-361794.html

一个比较完整的C编译器

我来回复

您尚未登录,请登录后再回复。点此登录或注册