I am to implement a parser using lex/yacc for the definitions of variables in c language. For example:
int x,y,z;
double a,b;
char c;
and then assign values to the variables. For example:
x = 2
a=2.5
c = 't'
I want to try with int and double for the start so that once it works I modify and introduce char definition and assignment but as it stands now I am unable to define a variable on a single line with my code. Anytime I try I get syntax error. This is the error I get:
double t,y,e;
doublet,ysyntax error
I am hoping there are guys out there to help me solve this problem.
lex file
edited.lex
%{
#include <ctype.h>
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
/* include YACC symbol encoding */
#include "calc.h"
#include "edited.tab.h"
char varname[256];
%}
%option noyywrap
DIGIT [0-9]+
ID [a-zA-Z][a-zA-Z0-9]*
%%
symbtbl *ptr; /* local variable */
int|float|double|char { ECHO;return DATATYPE; }
[[:space:]] /* skip spaces */
{DIGIT}+"."{DIGIT}*|"."{DIGIT}+ {sscanf(yytext,"%lg",&yylval.val); ECHO;return DECIMAL;}
"'"."'" {sscanf(yytext,"%c",&yylval.vchar); ECHO;return CHARACTER;}
"," { return yytext[0];}
";" { return yytext[0];}
{ID} {strcpy(varname,yytext); yylval.sptr=varname;ECHO; return VAR;}
%%
yacc file edited.y
%{
/* math functions */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "calc.h"
/* custom data structure definitions */
}*/
%}
/* bison data types for symbols */
%union{
double val; /* numeric data */
char vchar;
/* reference to variables*/
symbtbl *sptr;
}
%start Program
%token <val>DECIMAL
%token <vchar>CHARACTER
%token <sptr> VAR
%token DATATYPE
%left declaration_list
%type <val> declaration_list
%type <val> assignment_variable
%type <val> exp
%%
Program : Program statement
;
statement : vardef
| assignment_variable
;
vardef : DATATYPE declaration_list ';'|vardef
;
declaration_list : VAR {$1->value.var;printf("%s",$1->value.var);}
| declaration_list ',' VAR {$1->value.var;}
;
assignment_variable : VAR '=' exp ';' {$1->value.var=$3;}
;
exp : DECIMAL {$$=$1;}
;
/*
* error message handling
*/3
%%
#include <stdio.h>
#include <ctype.h>
char *p;
yyerror(char *s) {
printf("%s\n",s);
}
main( argc, argv )
char *argv[];
{
p = argv[0];
yyparse();
}
symbol table utils.c
/*
* Symbol table management functions
*/
#include <string.h>
#include <stdlib.h>
#include "calc.h"
/* head of symbol table list */
symbtbl *st=NULL;
/* add a symbol to table given name and type */
symbtbl *putsymb(char *name, int type) {
symbtbl *ptr;
if((ptr=(symbtbl *)(malloc(sizeof(symbtbl))))==NULL) {
return(NULL); /* allocation failed */
}
ptr->name = strdup(name);
if(ptr->name==NULL) {
free(ptr);
return(NULL); /* allocation failed */
}
ptr->type=type;
ptr->value.var=0;
/* add to list */
ptr->next=st;
st=ptr;
return ptr;
}
/* get a symbol from table */
symbtbl *getsymb(char *name) {
symbtbl *ptr;
/* scan the list for element */
for(ptr=st;ptr!=NULL;ptr=ptr->next)
if(!strcmp(ptr->name,name))
return ptr;
return(NULL); /* not found */
}
header file calc.h
/*
* Symbol Table element
* The Symbol Table is a list of entries
* that represent variables or functions
*/
typedef struct SymbTbl {
char *name; /* symbol name */
int type; /* symbol type VAR|FNCT */
union {
double var; /* variable value */
double (*fnctptr)(); /* function pointer */
} value; /* value/function associated to symbol */
struct SymbTbl *next; /* list forward pointer */
} symbtbl;
/* global variables */
extern symbtbl *st; /* head of symbol table list */
/* function prototypes */
symbtbl *putsymb(char *,int);
symbtbl *getsymb(char *);
DIGIT
rule includes a+
at the end; adding+
or*
when you use it is, at best, inviting confusion. It isn't clear to me how you get a token back for=
signs. Your sample C assignments are missing semicolons. – Jonathan Leffler