如何在符号表中存储实数(双精度)的值

时间:2016-12-23 13:59:34

标签: c parsing bison flex-lexer yacc

我正在开发一个迷你项目,要求它提供一个允许读取使用的源程序文件的编译器 语言指令并执行词法和句法分析并显示程序的结果。当我声明一个整数时,它工作正常,我能够使用"写"或使用"读取"读取其值。问题是,当我声明一个双重标识符时,它向我显示它是一个未声明的标识符。 这是我的代码。

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);
}



/*-------------------------------------------*/

0 个答案:

没有答案