Combination of lex and YACC When combined with Lex and YACC, you can easily generate a compilation program in a new language. However, many domestic books have separated their introductions, the separate introduction is also vague and not clear. The introduction of how they are combined is even less pitiful. I used them to build a compilation program that can recognize integer values, such as addition, subtraction, multiplication, and division. Write down my experiences below for your reference.
First of all, I will not introduce the syntax rules of lex, because these are the key content in some books. I will first write the Lex source program below and then explain it. % { # Define number 257 # Define plus (258) # Define sub259 # Define chen260 # Define Div 261. # Define lkuo 262 # Define ykuo 263 # Include <stdio. h> # Include <stdlib. h> Extern int yylval; %} Number [0-9] + % {Number} {yylval = atoi (yytext); printf ("% s", yytext); return number ;} "+" {Printf ("% s", yytext); return plus ;} "-" {Printf ("% s", yytext); Return sub ;} "*" {Printf ("% s", yytext); Return Chen ;} "/" {Printf ("% s", yytext); Return div ;} "(" {Printf ("% s", yytext); Return lkuo ;} ")" {Printf ("% s", yytext); Return ykuo ;} % Where # Define number 257 # Define plus (258) # Define sub259 # Define chen260 # Define Div 261. # Define lkuo 262 # Define ykuo 263 It is a mark used in YACC. It must be defined in YACC first, and then used in lex. YACC tells Lex the symbol to be used and uses the YACC-D file. Y to generate a yytab. h file, in which the content is the above Series # define .... Extern int yylval; tells Lex to reference the external variable yylval. % {Number} {yylval = atoi (yytext); printf ("% s", yytext); return number ;} "+" {Printf ("% s", yytext); return plus ;} "-" {Printf ("% s", yytext); Return sub ;} "*" {Printf ("% s", yytext); Return Chen ;} "/" {Printf ("% s", yytext); Return div ;} "(" {Printf ("% s", yytext); Return lkuo ;} ")" {Printf ("% s", yytext); Return ykuo ;} % This part will not be explained. Below is the *. y File % { # Include <stdio. h> # Include <stdlib. h> # Include <string. h> # Include <ctype. h> # Define yystype int %} % Token number % Token plus % Token sub % Token plus % Token Chen % Token Div % Token lkuo % Token ykuo % Left plus sub % Left Chen Div % COM: exp {printf ("= % d/N", $1 );}; Exp: EXP plus FAC {$ = =$ 1 + $3 ;} | Exp sub FAC {$ = =$ 1-$3 ;} | FAC {$ = $1 ;}; FAC: FAC Chen term {$ = =$ 1*$3 ;} | FAC Div term {$ = =$ 1/$3 ;} | Term {$ = $1 ;}; Term: lkuo exp ykuo {$ =$ 1 ;} | Number {$ = $1 ;}; % Extern int yylex (); Int yyparse (); Main () { Return yyparse (); } Yyerror () {Printf ("sytax error ");} Where # define yystype int is the type of the value stack that defines the record mark as Int. Of course, you can also define other types. We name the first file as sample. L. Run the pclex sample. l command to generate the sample. c file. Then we name the second file sample1.y and run the command pcyacc-v-D sample1.y. Generate sample1.c, yytab. H, and yy. LRT (analysis table file of YACC ). Use VC ++ or TC to compile a project. This project contains these two files *. c file, where sample1.c is the primary file (this option is set in the compile item in TC) when compiling this project in TC, generate an executable file. For example, after editing a niu.txt file, the niu.txt file is a mathematical expression to be recognized. Example: The content of niu.txt is as follows: 5-2 + 3*22/2 + 2-3 The execution result with niu1 <niu.txt is as follows: For example, the content of niu.txt is as follows: Try a wrong syntax If the content of niu.txt is as follows: 5-3 + 2 +/4*2 + 4 red indicates that the execution result is as follows: I use sytax error to indicate a syntax error. There are still many imperfections in this compilation program, but it has outlined a framework used by Lex and YACC. If you are interested, you can gradually improve it.
|