lex(Lexical Analyzar)内部定义的一些变量和函数
内部预定义变量:
yytext char * 当前匹配的字符串
yyleng int 当前匹配的字符串长度yyin FILE * lex当前的解析文件,默认为标准输出
yyout FILE * lex解析后的输出文件,默认为标准输入
yylineno int 当前的行数信息
内部预定义宏:
ECHO #define ECHO fwrite(yytext, yyleng, 1, yyout) 也是未匹配字符的默认动作
内部预定义的函数:
int yylex(void) 调用Lex进行词法分析int yywrap(void) 在文件(或输入)的末尾调用。如果函数的返回值是1,就停止解析。 因此它可以用来解析多个文件。代码可以写在第三段,这 样可以解析多个文件。 方法是使用 yyin 文件指针指向不同的文件,直到所有的文件都被解析。最后,yywrap() 可以返回1,来表示解析的结束。
lex总结
Lex其实就是词法分析器,通过配置文件*.l,依据正则表达式逐字符去顺序解析文件,
并动态更新内存的数据解析状态。不过Lex只有状态和状态转换能力。因为它没有堆栈,
它不适合用于剖析外壳结构。而yacc增加了一个堆栈,并且能够轻易处理像括号这样的
结构。Lex善长于模式匹配,如果有更多的运算要求就需要yacc了。
lexya.l
%{
#include <stdlib.h>
void yyerror(char*);
#include "lexya.tab.h"
%}
%%
[0-9]+ {yylval=atoi(yytext);return INTEGER;}
[-+*/\n] return *yytext;
[\t] ;
. yyerror("error character");
%%
int yywrap()
{
return 1;
}
lexya.y
%{
#include <stdio.h>
#include <stdlib.h>
int yylex();
void yyerror(char*);
%}
%token INTEGER
%left '+''-'
%left '*' '/'
%%
program:
program expr '\n' {printf("%d\n",$2);}
|
;
expr:
INTEGER {$$=$1;}
|expr '*' expr {$$=$1*$3;}
|expr '/' expr {$$=$1/$3;}
|expr '+' expr {$$=$1+$3;}
|expr '-' expr {$$=$1-$3;}
;
%%
void yyerror(char* s)
{
printf("%s\n",s);
}
int main()
{
yyparse();
return 0;
}
bison -D lexya.y
lex lexya.l
gcc -o parser *.c