Lex Yacc学习

前言

  刚接触lex yacc,学习一下!!http://www.cnblogs.com/welkinwalker/archive/2012/04/09/2439065.html相关内容来源于上述博客

lex是什么?

  lex:lexical analysis,词法分析。符号提取。实际上这是提取编程语言占用的各种保留字、操作符等等语言的一种解决措施。

  它的另外一个名字scanner,就有扫描的意思。

  lex把每个扫描出来的单词统统叫做token,token可以有很多类。对比自然语言的话,英语中的每个单词都是token,token有很多类,比如non(名词)就是一个类token,apple就是属于这个类型的一个具体token。对于某个编程语言来说,token的个数是很有限的,可以理解为在文件中的关键字。

  lex工具会帮我们生成一个yylex函数,yacc通过调用这个函数来得知拿到的token是什么类型的,但是token的类型是在yacc中定义的。

  lex的输入文件一般会被命名为.l文件,通过lex XX.l我们得到输出文件是lex.yy.c

yacc是什么?

  yacc:syntactic analysis,语法分析。有lex提取了单词再有yacc做语法表达。

  yacc帮我们生成一个yyparse函数,这个函数不断调用上面的yylex函数来得到token的类型。

  yyac的输入文件一般会被命名成.y文件,通过yacc -d XX.y我们得到的输出文件是y.tab.h y.tab.c,前者包含了lex需要的token类型定义,需要被include进.l文件中。

Lex和yacc的输入文件格式

Definition section
%%
Rules secition
%%
C code seciton

.l和.y的文件格式都是分成三段,用%%来分割,三个section的含义是:

  • Definition Section
    • 这块可以放C语言的各种各样include,define等声明语句,但是要用%{%}括起来。
    • 如果是.l文件,可以放预定义的正则表达式:minus"-"还要放token的定义,方法是:代号正则表达式。然后到了,Rules Seciton就可以通过{符号}来引用正则表达式
    • 如果是.y文件,可以放token的定义,如:%token INTEGER PLUS,这里定义的每个toekn都可以在y.tab.h中看到。
  • Rules section
    • .l文件在这里放置的rules就是每个正则表达式要对应的动作,一般是返回一个token
    • .y文件在这里放置的rules就是满足一个语法描述时要执行的动作
    • 无论是.l文件还是.y文件这里的动作都是用{}括起来的,用C语言来描述,这些代码可以做你任何想做的事情
  • C code Section
    • main函数,yyerror函数等的定义

 lex和yacc能帮我们做什么??

  解释执行自定义语言。有几点注意:

  1. 自定义语言要做的事情必须可以通过C语言来实现。lex和yacc存在的意义在于简化语言,让使用者能够以一种比较简单的语言来实现复杂的操作。比如:对于数据库的查询肯定有现成的库可以来完成,但是使用起来比较麻烦,要自己写函数调用API,编译才行。如果我们想连接自定义的简单语言(SQL)来实现操作,这个时候就可以用lex和yacc
  2. lex和yacc做的事情只是:用C语言来实现另外一个语言。所以,他没办法实现C语言自己,但是可以实现java、python等。当然你可以通过Antlr来实现C语言的解析和执行,如果你怎么做的话,C语言程序首先是通过java来执行,然后java又变成了本地语言(C语言)来执行。

使用lex和yacc我们要做那几件事情?

  1. 定义各种token类型。他们在.y中定义,这些token既会被lex使用到,也会被.y文件中的BNF使用到。
  2. 写词汇分析代码。这部分代码在.I文件(就是lex输入文件)中。这块的定义方式是:正则表达式->对应操作。如果和yacc一起来使用的话,对应的操作通常是返回一个token类型,这个token的类型要在yacc中提前定义好。
  3. 写BNF。这些东西定义了语言的规约方式。

关于BNF

是一种context-free grammars

在yacc中定义的方式其实是:

<symbol>:_expression_{operation}

|_expression_{operation}

operation是满足语法时要执行的C语言代码,这里的C语言代码可以使用一些变量,他们是:$$$1$2等等。$$代表规约的结果,就是表达式_expression_的值,$1代表的是前面_expression_中出现的各个word。举个例子:

 

posted @ 2016-06-30 14:18  smile带着你  阅读(199)  评论(0编辑  收藏  举报