我正在开发一个迷你项目,要求它提供一个允许读取使用的源程序文件的编译器 语言指令并执行词法和句法分析并显示程序的结果。当我声明一个整数时,它工作正常,我能够使用"写"或使用"读取"读取其值。问题是,当我声明一个双重标识符时,它向我显示它是一个未声明的标识符。 这是我的代码。
Simple.lex
%{
#include <string.h>
#include <stdlib.h>
#include "Simple.tab.h"
%}
DIGIT [0-9]
ID [a-z]
%%
"=" { return(ASSGNOP); }
{DIGIT}+ { yylval.intval = atoi( yytext ); return(NUMBER); }
integer { return(INTEGER); }
real { return(FLOAT); }
read { return(READ); }
write { return(WRITE); }
{ID} { yylval.id = (char *) strdup(yytext);return(IDENTIFIER); }
[ \t\n]+ /* eat up whitespace */{};
. { return(yytext[0]);}
%%
int yywrap(void){}
Simple.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ST.h"
#include "SM.h" //Stack Machine
#include "CG.h" //Code Generator
#define YYDEBUG 1 //For Debugging
int errors; //Error Count
//---------------------------------------------------------------------
//---------------------------------------------------------------------
struct lbs * newlblrec() /* Allocate space for the labels*/
{
return (struct lbs *) malloc(sizeof(struct lbs));
}
//------------------------------------------
ajouter_variable ( char *sym_name )
{
symrec *s;
s = getsym (sym_name);
if (s == 0)
s = putsym (sym_name);
else { errors++;printf( "%s declared identifier \n", sym_name );}
}
//------------------------------------------------------
rechercher( enum code_ops operation, char *sym_name )
{ symrec *identifier;
identifier = getsym( sym_name );
if ( identifier == 0 )
{ errors++; printf( "%s", sym_name );
printf( "%s\n", " unddeclared identifier " );
}
else gen_code( operation, identifier->offset );
}
%}
//---------------------------------------
%union semrec /* The Semantic Records */
{
int intval; /* Integer values */
float floatval; /*les valeurs d'un reel*/
char *id; /* Identifiers */
struct lbs *lbls; /* For backpatching */
}
//-------------------------------------------------------------------------
%start program
%token <intval> INTEG /* Simple integer*/
%token <floatval> FLOA /* Simple double*/
%token <id> IDENTIFIER
%token MESSAGE /* Simple identifier */
%token INTEGER FLOAT READ WRITE
%token ASSGNOP
//---------------------------------------------------------------------------
%left '-' '+'
%left '*' '/'
//---------------------------------------------------------------------------
%%
program :
declarations
commands
;
declarations :
| declarations declaration
;
declaration : /* empty */
INTEGER id_seq IDENTIFIER ';' { ajouter_variable( $3 );}
|FLOAT id_seq IDENTIFIER ';' { ajouter_variable( $3 );}
;
id_seq : /* empty */
| id_seq IDENTIFIER ',' { ajouter_variable( $2 ); }
;
commands : declarations
| commands command ';'
;
command :
| READ IDENTIFIER { rechercher( READ_INT, $2 ); }
| WRITE exp { gen_code( WRITE_INT, 0 ); }
| WRITE exp { gen_code( WRITE_FLOAT, 0 ); }
| WRITE message {printf("%s",$2);}
| IDENTIFIER ASSGNOP exp { rechercher( STORE, $1 ); }
;
exp : INTEG { gen_code( LD_INT, $1 ); }
| FLOA { gen_codef( LD_FLOAT, $1 ); }
| IDENTIFIER { rechercher( LD_VAR, $1 ); }
| exp '+' exp { gen_code( ADD, 0 ); }
| exp '-' exp { gen_code( SUB, 0 ); }
| exp '*' exp { gen_code( MULT, 0 ); }
| exp '/' exp { gen_code( DIV, 0 ); }
| '(' exp ')'
;
message:
|'*'message'*'
;
%%
main( int argc, char *argv[] )
{ extern FILE *yyin;
++argv; --argc;
yyin = fopen( argv[0], "r" );
/*yydebug = 1;*/
errors = 0;
yyparse ();
printf ( "Parse Completed\n" );
if ( errors == 0 )
{ print_code ();print_codef ();fetch_execute_cycle();
}
}
/*=========================================================================
YYERROR
=========================================================================*/
yyerror ( char *s ) /* Called by yyparse on error */
{
errors++;
printf ("%s\n", s);
}
/**************************** End Grammar File ***************************/
ST.h:
struct symrec
{
char *name; /* name of symbol */
int offset; /* data offset */
double offsetf;
struct symrec *next; /* link field */
};
typedef struct symrec symrec;
symrec *identifier;
symrec *sym_table = (symrec *)0;
//----------------------------------------------------------
symrec * putsym (char *sym_name)
{
symrec *ptr;
ptr = (symrec *) malloc (sizeof(symrec));
ptr->name = (char *) malloc (strlen(sym_name)+1);
strcpy (ptr->name,sym_name);
ptr->offset = data_location();
ptr->offsetf = data_locationf();
ptr->next = (struct symrec *)sym_table;
sym_table = ptr;
return ptr;
}
//----------------------------------------------------------
symrec * getsym (char *sym_name)
{
symrec *ptr;
for ( ptr = sym_table;ptr != (symrec *) 0;ptr = (symrec *)ptr->next )
if (strcmp (ptr->name,sym_name) == 0){return ptr;}
return 0;
}
/************************** End Symbol Table **************************/
CG.h
int data_offset = 0; /* Initial offset */
int data_location() /* Reserves a data location */
{
return data_offset++;
}
int code_offset = 0; /* Initial offset */
int gen_label() /* Returns current offset */
{
return code_offset;
}
int reserve_loc() /* Reserves a code location */
{
return code_offset++;
}
/* Generates code at current location */
void gen_code( enum code_ops operation, int arg )
{ code[code_offset].op = operation;
code[code_offset++].arg = arg;
}
/* Generates code at a reserved location */
void back_patch( int addr, enum code_ops operation, int arg )
{
code[addr].op = operation;
code[addr].arg = arg;
}
void print_code()
{
int i = 0;
}
/*---------------------------------------------------------------------------*/
double data_offsetf = 0.0;
double data_locationf()
{
return data_offsetf++;
}
double code_offsetf = 0.0;
double gen_labelf()
{
return code_offsetf;
}
double reserve_locf()
{
return code_offsetf++;
}
/* Generates code at current location */
void gen_codef( enum code_ops operationf, double argf )
{ code[code_offsetf].opf = operationf;
code[code_offsetf++].argf = argf;
}
/* Generates code at a reserved location */
void back_patchf( double addrf, enum code_ops operationf, double argf )
{
code[addrf].op = operationf;
code[addrf].argf = argf;
}
void print_codef()
{
double i = 0.0;
}
SM.h
/***************************************************************************
Stack Machine
***************************************************************************/
/*=========================================================================
DECLARATIONS
=========================================================================*/
/* OPERATIONS: Internal Representation */
enum code_ops { HALT, STORE, JMP_FALSE, GOTO, DATA, LD_INT,LD_FLOAT,WRITE_FLOAT,LD_INT, LD_VAR, READ_INT, WRITE_INT, ADD, SUB, MULT, DIV};
/* OPERATIONS: External Representation */
char *op_name[] = {"halt", "store", "goto","data", "ld_int","write float","ld_float", "ld_var","in_int", "out_int","lt","add", "sub", "mult", "div"};
/*=========================================================================*/
struct instruction
{
enum code_ops op;
int arg;
double argf;
};
/*=========================================================================*/
struct instruction code[999];
struct instruction ir;
int stack[999];
double stackf[999];
int pc = 0;
int ar = 0;
int top = 0;
char ch;
double pcf = 0.0;
double arf = 0.0;
double topf = 0.0;
/*=========================================================================*/
void fetch_execute_cycle()
{ do { ir = code[pc++];
switch (ir.op)
{
case HALT : printf( "halt \n" ); break;
case READ_INT : printf( "-->input: " );stack[ar+ir.arg]=stack[top++];scanf( "%ld", &stack[ar+ir.arg] ); break;
case WRITE_INT : printf( "-----> output: %d\n", stack[top] ); break;
case WRITE_FLOAT : printf( "-----> output: %lf\n", stackf[topf] ); break;
case STORE : stack[ir.arg] = stack[top++]; break;
case GOTO : pc = ir.arg; break;
case DATA : top = top + ir.arg; break;
case LD_INT : stack[++top] = ir.arg; break;
case LD_FLOAT : stackf[++topf] = ir.argf; break;
case LD_VAR : stack[++top] = stack[ar+ir.arg]; break;
break;
case ADD : stack[top-1] = stack[top-1] + stack[top];
top--;
break;
case SUB : stack[top-1] = stack[top-1] - stack[top];
top--;
break;
case MULT : stack[top-1] = stack[top-1] * stack[top];
top--;
break;
case DIV : stack[top-1] = stack[top-1] / stack[top];
top--;
break;
default : printf( "%soperateur non juste\n" );
break;
}
}
while (ir.op != HALT);
}
/*-------------------------------------------*/