Lex and YACC application tutorial (3). Use Variables

Source: Internet
Author: User

Lex and YACC application tutorial (3). Use Variables

Papaya 20070512

I. Sequencing

As early as two months ago, I wanted to elaborate on Lex and YACC. However, there were too many work tasks and it was hard to leave them empty.
Calm down and learn by summary. I am not aware of the bad working environment in China. It is common to work overtime and I am basically doing this all day.
A lot of simple repetition, or even useless.

In the article Lex first, I summarized Lex from the perspective of getting started. The article Lex and YACC can be simple.
Based on the lex situation, this paper introduces the theory of lex and YACC algorithms, and explains how to combine Lex and YACC
.

Here we need to further study the use of lex and YACC in order to understand the syntax tree that will be introduced later.

<The address of this series of articles: http://blog.csdn.net/liwei_cmg/category/207528.aspx>
All examples in this series have passed the RedHat Linux 8 test.

Ii. Example

On the basis of the previous steps, we took a further step to design a simple calculator, which includes four operations: +,-, *,/, and
Supports the () operator, where the values can be saved as variables and internal analysis information is printed.

All contents of the lex file (lexya_ B .l ):
---------------------------------------------

% {
# Include <stdlib. h>
# Include "lexya_ B .tab.h"
Void yyerror (char *);
Void add_buff (char *);

Extern char sbuff [10] [20];
Extern int IX;
Extern int Iy;
%}
%
[A-Z] {yylval = * yytext; add_buff (yytext); Return var ;}
[0-9] + {yylval = atoi (yytext); add_buff (yytext); Return int ;}
[-+ () = */] {Yylval = * yytext; add_buff (yytext); return * yytext ;}
[/N] {yylval = * yytext; Iy = 0; ix ++; return * yytext ;}
[/T];/* remove Spaces */
. Yyerror ("invalid character ");
%
Void add_buff (char * buff ){
Sbuff [ix] [Iy] = * Buff; Iy ++;
}
Int yywrap (void ){
Return 1;
}

Full YACC file content (lexya_ B .y ):
---------------------------------------------

% {
# Include <stdlib. h>
Int yylex (void );
Void yyerror (char *);
Void debuginfo (char *, int *, char *);
Void printinfo ();

Int smem [256];
Char sbuff [10] [20] = {0 };
Int IX = 0;
Int Iy = 0;

%}
% Token int VaR
% Left '+ ''-'
% Left '*''/'
%
Program:
Program Statement
|
;
Statement:
Expr {printf ("% d/N", $1 );}
| Var '= 'expr {debuginfo ("=", yyvsp, "110"); smem [$1] = $3 ;}
| Statement '/N' {printf ("----------------------------------/n ");}
;
Expr:
Int {debuginfo ("int", yyvsp, "0"); $ = $1 ;}
| Var {debuginfo ("Var", yyvsp, "1"); $ = smem [$1];}
| Expr '*' expr {debuginfo ("*", yyvsp, "010"); $ = $1*$3 ;}
| Expr '/'expr {debuginfo ("/", yyvsp, "010"); $ = $1/$3 ;}
| Expr '+ 'expr {debuginfo ("+", yyvsp, "010"); $ = $1 + $3 ;}
| Expr '-' expr {debuginfo ("-", yyvsp, "010"); $ = $1-$3 ;}
| '('Expr')' {debuginfo ("()", yyvsp, "101"); $ =$ 2 ;}
;
%
Void debuginfo (char * info, int * VSP, char * mark ){
/**/
Printf ("-- rule: % s/n", Info );
Int I = 0;
Int ilen = strlen (Mark );
For (I = 0; I >= 1-ilen; I --){
If (MARK [ilen + I-1] = '1 ')
Printf ("$ % d % C/N", I + ilen, VSP [I], VSP [I]);
Else
Printf ("$ % d/N", I + ilen, VSP [I]);
}
Printinfo ();

}
Void printinfo (){
Int I = 0;
Printf ("-- Statement:/N ");
/*
For (I = 0; I <= IX; I ++)
Printf ("% s/n", sbuff [I]);
*/
If (Iy = 0)
Printf ("% s/n", sbuff [iX-1]);
Else
Printf ("% s/n", sbuff [ix]);
 
Printf ("/N ");
}
Void yyerror (char * s ){
Printf ("% s/n", S );
}
Int main (void ){
Yyparse ();
Return 0;
}

Compile the full content of the file script (yacclex:
---------------------------------------------

Rm lexya _ $1. Tab. c
Rm lexya _ $1. Tab. h
Rm Lex. yy. c
Bison-D lexya _ $ 1.y
Lex lexya _ $ 1.l
Gcc-g-o parser Lex. yy. c lexya _ $1. Tab. c

All content of the compiled text to be interpreted:
---------------------------------------------

A = 4 + 2 * (3-2-1) + 6
B = 1-10/(6 + 4) + 8
C = A-B
A
B
C

Enter the command line to compile the compiler:
./Yacclex B

Into the file for explanation:
./Parser <Input

10
8
2

Variables are successfully used in this article, and the operator operation Priority is no problem.

In fact, I have read the article "Lex and YACC application method (II). Then I read YACC, and it is very easy to understand the above example.
Loose.

Here we just made some expansion changes:
1. added the Global Array smem to store variables. However, variable names are limited and only single characters are supported.
2. added the Global Array sbuff to store the analyzed statements.
3. Added debuginfo to print stack information.
4. Added printinfo to print the current analysis statement.

To perform internal analysis, you need to analyze the generated C file and track and debug the program (parser.
(Note: When lex is compiled with the D parameter, detailed debugging information is output during program interpretation. For example, Lex-D lexya _ $ 1.l)
In this example, the actual analysis and understanding of lexya_ B .tab.c will further enhance the theory of lex and YACC.
Understanding.

4. Add supported variable characters

The preceding example only supports single-character variables. To support multiple characters, you must define a global variable, for example:

Struct varindex
{
Int ivalue;
Char Smark [10];
};

At the same time, the printing information is added to the display of variables. The following lists all the file content, which is relatively simple and no longer
Additional instructions.

Header file (userdef. h)

Typedef struct {
Int ivalue;
Char Smark [10];
} Varindex;
Varindex strmem [256];

Lex file:

% {
# Include <stdlib. h>
# Include "userdef. H"
# Include "lexya_c.tab.h"

Void yyerror (char *);
Void add_buff (char *);
Void add_var (char *);

Extern char sbuff [10] [20];
Extern int ibuffx;
Extern int ibuffy;

Extern varindex strmem [256];
Extern int imaxindex;
Extern int icurindex;

%}
%
[A-Za-Z] [a-zA-Z0-9] * {add_var (yytext); yylval = icurindex; add_buff (yytext); Return var ;}
[0-9] + {yylval = atoi (yytext); add_buff (yytext); Return int ;}
[-+ () = */] {Yylval = * yytext; add_buff (yytext); return * yytext ;}
[/N] {yylval = * yytext; ibuffy = 0; ibuffx ++; return * yytext ;}
[/T];/* remove Spaces */
. Yyerror ("invalid character ");
%
Void add_buff (char * buff ){
Strcat (sbuff [ibuffx], buff );
Ibuffy + = strlen (buff );
}
Void add_var (char * mark ){

If (imaxindex = 0 ){
Strcpy (strmem [0]. Smark, mark );
Imaxindex ++;
Icurindex = 0;
Return;
}

Int I;
For (I = 0; I <= iMaxIndex-1; I ++ ){
If (strcmp (strmem [I]. Smark, mark) = 0 ){
Icurindex = I;
Return;
}
}

Strcpy (strmem [imaxindex]. Smark, mark );
Icurindex = imaxindex;
Imaxindex ++;

}
Int yywrap (void ){
Return 1;
}

YACC file:

% {
# Include <stdlib. h>
# Include "userdef. H"
Int yylex (void );
Void yyerror (char *);

Void debug_info (char *, int *, char *);
Void pai_info ();

Extern varindex strmem [256];

Int imaxindex = 0;
Int icurindex = 0;

Char sbuff [10] [20] = {0 };
Int ibuffx = 0;
Int ibuffy = 0;

%}
% Token int VaR
% Left '+ ''-'
% Left '*''/'
%
Program:
Program Statement
|
;
Statement:
Expr {printf ("% d/N", $1 );}
| Var '= 'expr {debug_info ("=", yyvsp, "210"); strmem [$1]. ivalue = $3 ;}
| Statement '/N' {printf ("----------------------------------/n ");}
;
Expr:
Int {debug_info ("int", yyvsp, "0"); $ = $1 ;}
| Var {debug_info ("Var", yyvsp, "2"); $ = strmem [$1]. ivalue ;}
| Expr '*' expr {debug_info ("*", yyvsp, "010"); $ = $1*$3 ;}
| Expr '/'expr {debug_info ("/", yyvsp, "010"); $ = $1/$3 ;}
| Expr '+ 'expr {debug_info ("+", yyvsp, "010"); $ = $1 + $3 ;}
| Expr '-' expr {debug_info ("-", yyvsp, "010"); $ = $1-$3 ;}
| '('Expr')' {debug_info ("()", yyvsp, "101"); $ =$ 2 ;}
;
%
Void debug_info (char * info, int * VSP, char * mark ){
/**/
Printf ("-- rule: % s/n", Info );
Int I = 0;
Int Ile

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.