参考链接: Lex使用指南

下载

sudo apt-get install flex

要求

实现C-语言词法分析器,每个Token以<名称,属性值>打印,有5种Tokens,最后通过示例程序验证
未命名图片.png
示例程序

  1. /*A program to perform Euclid's
  2. Algorithm to compute gcd. */
  3. int gcd (int u,int v){
  4. if (v==0) return u;
  5. else return gcd(v, u-u/v*v);
  6. /*u-u/v*v == u mod v */
  7. }
  8. void main(void){
  9. int x;
  10. int y;
  11. x = input();
  12. y = input();
  13. output(gcd(x,y));
  14. }

实现

新建lex.l文件进行编辑

  1. %{
  2. #include<stdio.h>
  3. %}
  4. delim [ \t\n]
  5. ws {delim}+
  6. letter [A-Za-z]
  7. digit [0-9]
  8. id {letter}{letter}*
  9. num {digit}{digit}*
  10. comments "/*"([^\*]|(\*)*[^\*/])*(\*)*"*/"
  11. %%
  12. {ws}
  13. else |
  14. if |
  15. int |
  16. return |
  17. void |
  18. while {printf("<keyword, %s>\n", yytext);}
  19. {id} {printf("<ID, %s>\n", yytext);}
  20. {num} {printf("<NUM, %s>\n", yytext);}
  21. {comments} {printf("<COMMENTS, %s>\n", yytext);}
  22. "+" |
  23. "-" |
  24. "*" |
  25. "/" |
  26. "<" |
  27. "<=" |
  28. "==" |
  29. ">" |
  30. ">=" |
  31. "!=" |
  32. "=" |
  33. ";" |
  34. "," |
  35. "'" |
  36. "(" |
  37. ")" |
  38. "[" |
  39. "]" |
  40. "{" |
  41. "}" {printf("<symbol, %s>\n", yytext);}
  42. %%
  43. int main(){
  44. if ((yyin = fopen("./gcd.c","r"))==NULL){
  45. printf("Can't open file!\n");
  46. return 1;
  47. }
  48. yylex();
  49. return 0;
  50. }

最复杂处为//注释的匹配,参考: Lex识别C风格字符串和注释

Bug

  • 直接复制代码时会出现各种字符编码,空格错误,最好手动敲入,保证两个%%识别无误(红色)
  • “[“和”]”始终匹配有误,需要在后面加一个空格”[ “ “] “

    运行

    完成.l文件后
    ①使用flex lex.l,将.l文件编译为.c文件(默认生成lex.yy.c)
    ②使用gcc [-o xxx.out] lex.yy.c -lfl编译.c文件为可执行文件
    ③使用./xxx.out直接运行(目录中要有yyin的指定输入文件)
    image.png