LEX和YACC的使用(例子)
1、簡(jiǎn)單C語(yǔ)言的詞法分析程序;
%{
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
%}
digit???????????[0-9]
letter??????????[A-Za-z]
other_char??????[!-@\[-~]
id??????????????({letter}|[_])({letter}|{digit}|[_])*
string??????????{({letter}|{digit}|{other_char})+}
int_num?????????{digit}+
%%
[ |\t|\n]+
"auto"|"double"|"int"|"struct"|"break"|"else"|"long"|"switch"|"case"|"enum"|"register"|"typedef"|"char"|"extern"|"return"|"union"|"const"|"float"|"short"|"unsigned"|"continue"|"for"|"signed"|"void"|"default"|"goto"|"sizeof"|"do"|"if"|"static"|"while"|"main"?????????{Upper(yytext,yyleng);printf("%s,NULL\n",yytext);}
\"([!-~])*\"????{printf("CONST_string,%s\n",yytext);}
-?{int_num}[.]{int_num}?([E][+|-]?{int_num})???????{printf("CONST_real,%s\n",yytext);}
"0x"?{int_num} {printf("CONST_int,%s\n",yytext);}
","|";"|"("|")"|"{"|"}"|"["|"]"|"->"|"."|"!"|"~"|"++"|"--"|"*"|"&"|"sizeof"|"/"|"%"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"&"|"^"|"|"|"&"|"||"|"+="|"-="|"*="|"/="|"%="|">>="|"<<="|"&="|"^="|"|="|"="????????{printf("%s,NULL\n",yytext);}
{id}????{printf("ID,%s\n",yytext);}
{digit}({letter})+???{printf("error1:%s\n",yytext);}
%%
#include <ctype.h>
Upper(char *s,int l)
{
????????int i;
????????for(i=0;i<l;i++)
????????{
????????????????s[i]=toupper(s[i]);
????????}
}
yywrap()
{
????????return 1;
}
注意:要得到輸出信息,需要自行添加main函數(shù),lex默認(rèn)的main函數(shù)沒(méi)有輸出的。main函數(shù)的寫(xiě)法與C語(yǔ)言的類似,要定義
輸入流指針yyin(如:yyin=(FILE*)fopen("text.txt","rt") )。
2、算術(shù)表達(dá)式的分析程序:
Lex程序:
%{
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define false 0
#define ture 1
#include "myYacc.tab.h"
extern int lexverbose;
extern int linecount;
%}
digit?[0-9]
letter?[a-zA-Z]
%%
{digit}+\.{digit}*???{
???yylval.real=(float)atof(yytext);
???if(lexverbose)
??????printf("real:%g\n",yylval.real);
???return(number);
???}
\+???{
???yylval.chr=yytext[0];
???if(lexverbose)
?????printf("opterator:%c\n",yylval.chr);
???return('+');
???}
\-???{
???yylval.chr=yytext[0];
???if(lexverbose)
?????printf("oprator:%c\n",yylval.chr);
???return('-');
???}
\*???{
???yylval.chr=yytext[0];
???if(lexverbose)
???printf("oprator:%c\n",yylval.chr);
???return('*');
???}
\/???{
???yylval.chr=yytext[0];
???if(lexverbose)
?????printf("oprator:%c\n",yylval.chr);
???return('/');
???}
"("???{
???yylval.chr=yytext[0];
???if(lexverbose)
?????printf("separator:%c\n",yylval.chr);
???return('(');
???}
")"???{
???yylval.chr=yytext[0];
???if(lexverbose)
?????printf("separtor:%c\n",yylval.chr);
???return(')');
???}
;???{
???return(';');
???}
\n???{
???printf("line %d\n",linecount);
????????????????????????/*??linecount++;?????*/
???return('\n');
???}
[ \t]+??????????????????{
???printf("lexical analyzer error\n");
???}
quit??{
???printf("Bye!\n");
???exit(0);
???}
%%
int yywrap()
{
return(1);
}
Yacc程序;
%{
#include <ctype.h>
#include<stdio.h>
#define MSDOS
int linecount;
extern int yylex();
extern int yyerror();
%}
%union{
???char chr;
???char *str;
???int integer;
???float real;
???double dbl;
???}
%token number
%type <real> expr number
%left '+' '-'
%left '*' '/'
%right uminus
%%
lines:?lines expr'\n'
?{
??printf("line %d:%g\n",linecount++,$2);
?}
?|lines'\n'
?{
??linecount++;
?}
?|
?;
expr:???expr'+'expr
?{
??$$=$1+$3;
?}
?|expr '-' expr
?{
??$$=$1-$3;
?}
?|expr '*' expr
?{
??$$=$1*$3;
?}
?| expr '/' expr
?{
??$$=$1/$3;
?}
?| '(' expr ')'
?{
??$$=$2;
?}
?| '-' expr %prec uminus
?{
??$$=-$2;
?}
?| number
?;
%%
int yyerror(s)
char *s;
{
?fprintf(stderr,"syntactic error:%s\n",s);
?return 0;
}
C的主程序:
#include <stdlib.h>
#include <stdio.h>
int lexverbose=0;
extern int yyparse();
int main(int argc, char* argv[])
{
?extern FILE *yyin;
?printf("Compiling...!\n");
?if((yyin=fopen("exprTest.txt","rt"))==NULL){
???perror("can not open file test.txt\n") ;
???exit(1);
??}
?if (yyparse()==1){
??fprintf(stderr,"parser error\n");
??exit(1);
?}
?printf("yyparse() completed successfully!\n");
?return 0;
}
執(zhí)行時(shí),將lex和yacc編譯生成的C程序與最后的c語(yǔ)言主程序一起添加到一個(gè)空的C的工程中,再用GCC編譯即可。
以上實(shí)例在DEV C++ 4.9.9.2 下調(diào)試成功。
轉(zhuǎn)載于:https://www.cnblogs.com/dc2011/archive/2011/11/21/2256773.html
總結(jié)
以上是生活随笔為你收集整理的LEX和YACC的使用(例子)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 渗透工具环境篇——Cknife中国菜刀的
- 下一篇: 多图上传 - Web Uploader