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;
}



linux-0gt0:/tmp # flex test.l ; gcc lex.yy.c -ll ; ./a.out
1 + 1
2
11 * 12
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 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
flex 就是做语法分析的,不知道你想说什么.
不懂lex/yacc,不懂编译原理就不要瞎说

SST中国 发表于 2008-02-11 20:45

原帖由 cjaizss 于 2008-2-11 20:43 发表 http://linux.chinaunix.net/bbs/images/common/back.gif

不懂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

一般来说,语法分析比词法分析更难是因为语法有递归结构。
所以,语法分析器说到底可以做词法分析,但是反过来却很困难。
页: [1] 2
查看完整版本: 其实lex也可以做语法分析,只是复杂很多