Chinaunix

标题: 其实lex也可以做语法分析,只是复杂很多 [打印本页]

作者: cjaizss    时间: 2008-02-10 15:10
标题: 其实lex也可以做语法分析,只是复杂很多
打个比方:
%{
#include <stdio.h>
int a;
int op=0;
%}
%%
[0-9]+ {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(op==0){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&a);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int b;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(op) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 1:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a+b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 2:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a-b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 3:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a*b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case 4:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a/b);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;op=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
}
"+" {op=1;}
"-" {op=2;}
"*" {op=3;}
"/" {op=4;}
[\t \n]+ ;
. ;
%%
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yylex();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}



  1. linux-0gt0:/tmp # flex test.l ; gcc lex.yy.c -ll ; ./a.out
  2. 1 + 1
  3. 2
  4. 11 * 12
  5. 132
复制代码


以下程序和上面的功能一样,看起来更像lex程序
%{
#include <stdio.h>
int a;
int op=0;
%}
%s ADD SUB MUL DIV
%%
<ADD>[0-9]+ {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a+tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BEGIN INITIAL;
}
<SUB>[0-9]+ {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a-tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BEGIN INITIAL;
}
<MUL>[0-9]+ {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a*tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BEGIN INITIAL;
}
<DIV>[0-9]+ {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sscanf(yytext,"%d",&tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",a/tmp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BEGIN INITIAL;
}
[0-9]+ {sscanf(yytext,"%d",&a);}
"+" {BEGIN ADD;}
"-" {BEGIN SUB;}
"*" {BEGIN MUL;}
"/" {BEGIN DIV;}
[\t \n]+ ;
. ;
%%
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yylex();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}


[ 本帖最后由 cjaizss 于 2008-2-13 17:32 编辑 ]
作者: cjaizss    时间: 2008-02-10 15:11
以上只是简单的不带括号的四则运算
如果涉及到带括号的运算,则更加困难
作者: SST中国    时间: 2008-02-11 20:10
flex 就是做语法分析的,不知道你想说什么.
作者: cjaizss    时间: 2008-02-11 20:43
原帖由 SST中国 于 2008-2-11 20:10 发表
flex 就是做语法分析的,不知道你想说什么.

不懂lex/yacc,不懂编译原理就不要瞎说
作者: SST中国    时间: 2008-02-11 20:45
原帖由 cjaizss 于 2008-2-11 20:43 发表

不懂lex/yacc,不懂编译原理就不要瞎说


那我想听听你有何见解.
作者: SST中国    时间: 2008-02-11 20:47
Lex - A Lexical Analyzer Generator

难道不是词法分析?
作者: cjaizss    时间: 2008-02-11 21:11
flex 就是做语法分析的,不知道你想说什么.
Lex - A Lexical Analyzer Generator

难道不是词法分析?

以上两句是你一个人说的
作者: yecheng_110    时间: 2008-02-13 16:39
http://www.cppblog.com/FongLuo/archive/2008/02/04/42505.html
用“词法状态”实现的和LZ一样的功能?

[ 本帖最后由 cjaizss 于 2008-2-13 17:34 编辑 ]
作者: cjaizss    时间: 2008-02-13 17:34
标题: 回复 #8 yecheng_110 的帖子
呵呵,正是,以上我再用状态改写一下,让其更像lex
不好意思,点了编辑
作者: l.darkfire    时间: 2008-02-13 19:11
一般来说,语法分析比词法分析更难是因为语法有递归结构。
所以,语法分析器说到底可以做词法分析,但是反过来却很困难。
作者: Wind-Son    时间: 2008-02-13 21:53
你没发现lex只不过做了正则表达式的解析,真正的语法分析是你自己添加进去的?
这跟YACC利用lex的方式有啥区别?
而且你这里的语法分析都还算不上,只能生成树顶,连简单的 2*(2*(2+4))都识别不了,再复杂点还是回到YACC了
作者: cjaizss    时间: 2008-02-13 22:30
标题: 回复 #11 Wind-Son 的帖子
呵呵,这是自然,语法分析是自己做在里面的。
我在这里只是举个例子,复杂的四则运算其实也能做,自己构造即可
作者: prolj    时间: 2008-02-17 13:21
原帖由 SST中国 于 2008-2-11 20:47 发表
Lex - A Lexical Analyzer Generator

难道不是词法分析?

是,又怎么样?
作者: 海洋天空    时间: 2008-02-24 16:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: 海洋天空    时间: 2008-02-24 16:02
提示: 作者被禁止或删除 内容自动屏蔽
作者: 海洋天空    时间: 2008-02-24 16:03
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2