Reputation: 281
I am working on a compiler using lex & yacc. I am having compilation errors and I believe if I can get one item solved, the rest will fall into place. I compile the project as such:
gcc -ll *.c -o <program_name>
The error I am specifically talking about is the following:
In file included from scanner.lex:11:
y.tab.h:6: error: syntax error before "tree"
y.tab.h:6: warning: no semicolon at end of struct or union
y.tab.h:6: error: syntax error before '}' token
y.tab.h:6: warning: data definition has no type or storage class
y.tab.h:7: error: syntax error before "yylval"
y.tab.h:7: warning: data definition has no type or storage class
scanner.lex: In function `yylex':
scanner.lex:55: error: request for member `i' in something not a structure or union
scanner.lex:56: error: request for member `i' in something not a structure or union
scanner.lex:57: error: request for member `f' in something not a structure or union
I cannot see anything wrong with the struct at all. I am hoping someone can point our the error and suggest a correction. I will post more code if necessary. I am using yacc and lex, not flex or bison. As for the version, I cannot tell you that. GCC is version 3.4.5
I hate doing this but per a request I have added the complete code. Sorry, I really cannot "pair" it down to a compilable version.
The yacc file:
%{
#include "tree.h"
extern tree root;
%}
%token <i> Ident 1 IntConst 2
%token <f> RealConst 3
%token And 4 Array 5
%token <i> Begin 6
%token Boolean 7 Div 8 Do 9 Else 10
%token End 11 False 12 For 13 Goto 14 If 15
%token Imply 16 Integer 17 Label 18 Not 19 Or 20
%token Own 21 Procedure 22 Real 23 Step 24 String 25
%token Then 26 True 27 Until 28 Value 29 While 30
%token Plus 31 Minus 32 Mult 33 Divide 34 Less 35
%token LessEq 36 Great 37 GreatEq 38 Eq 39 NotEq 40
%token Comma 41 Colon 42 Semi 43 LParan 44 RParan 45
%token LBrak 46 RBrak 47 Assign 48
%start program
%union { tree t; int i; float f; }
%type <t> program block optdecls decl vardecl type idlist arraydecl arraylist arrayseg
%type <t> stmts stmt u_stmt assign dummy for_stmt if_stmt var factor term sum
%type <t> brel relation bsecond bfactor bterm expr a_expr
%%
program
: block
{ root = $1; }
;
block
: Begin optdecls stmts End
{ $$ = buildTree(Begin, $2, $3, buildTree(End,NULL, NULL,NULL)); }
;
optdecls
: /* empty */
{ $$ = NULL; }
| decl Semi optdecls
{ $$ = buildTree(Semi, $1, $3, NULL); }
/*{$$ = buildTree(Semicol,$1, NULL, NULL);$$->next = $3;} */
;
decl
: vardecl
{ $$ = $1; }
| arraydecl
{ $$ = $1; }
;
vardecl
: type idlist
{ $$->next = $2; $$ = $1; }
;
type
: Real
{ $$ = buildFloatTree(Real, $<f>1); }
| Integer
{ $$ = buildIntTree(Integer, $<i>1); }
| Boolean
{ $$ = buildIntTree(Boolean, $<i>1); }
;
idlist
: Ident
{ $$ = buildIntTree(Ident, $1); }
| Ident Comma idlist
{ $$ = buildTree(Comma, buildIntTree(Ident, $1), $3, NULL); }
;
arraydecl
: Array arraylist
{ $$ = buildTree(Array, $2, NULL, NULL); }
| type Array arraylist
{ $$ = buildTree(Array, $1, $3, NULL); }
;
arraylist
: arrayseg
{ $$ = $1; }
| arrayseg Comma arraylist
{ $$ = buildTree(Comma, $1, NULL, NULL);$$->next=$3 ; }
;
arrayseg
: Ident LBrak a_expr Colon a_expr RBrak
{ $$ = buildTree(LBrak, buildIntTree(Ident, $1), $3, $5); }
;
stmts
: stmt
{ $$ = $1; }
| stmt Semi stmts
{ $$ = buildTree(Semi, $1, NULL, NULL);$$->next=$3 ; }
;
stmt
: u_stmt
| if_stmt
| for_stmt
;
u_stmt
: assign
| dummy
| block
;
assign
: var Assign expr
{ $$ = buildTree(Assign, $1, $3, NULL); }
| var Assign assign
{ $$ = buildTree(Assign, $1, NULL, NULL);$$->next=$3; }
;
dummy
: /* empty */
{ $$ = NULL; }
;
for_stmt
: For var Assign a_expr Step a_expr Until a_expr Do stmt
{ $$ = buildTree(For, $2, $4, buildTree(Step, $6, $8, $10)); }
;
if_stmt
: If expr Then u_stmt
{ $$ = buildTree(If, $2, $4, NULL); }
| If expr Then u_stmt Else stmt
{ $$ = buildTree(If, $2, $4, $6); }
| If expr Then for_stmt
{ $$ = buildTree(If, $2, $4, NULL); }
;
var
: Ident
{ $$ = buildIntTree(Ident, $1); }
| Ident LBrak a_expr RBrak
{ $$ = buildTree(LBrak, buildIntTree(Ident, $1), $3, NULL); }
;
factor
: IntConst
{ $$ = buildIntTree(IntConst, $1); }
| RealConst
{ $$ = buildFloatTree(RealConst, $1); }
| var
{ $$ = $1; }
| LParan expr RParan
/* {$$ = buildTree(LParen, $2, NULL, NULL);} */
{ $$ = $2; }
;
term
: factor
{ $$ =$1; }
| term Mult factor
{ $$ = buildTree(Mult, $1, $3, NULL); }
| term Divide factor
{ $$ = buildTree(Divide, $1, $3, NULL); }
| term Div factor
{ $$ = buildTree(Div, $1, $3, NULL); }
;
sum
: term
{ $$ = $1; }
| Plus term
{ $$ = buildTree(Plus, $2, NULL, NULL); }
| Minus term
{ $$ = buildTree(Minus, $2, NULL, NULL); }
| sum Plus term
{ $$ = buildTree(Plus, $1, $3, NULL); }
| sum Minus term
{ $$ = buildTree(Minus, $1, $3, NULL); }
;
brel
: sum
{ $$ = $1; }
| True
{ $$ = buildTree(True, NULL, NULL, NULL); }
| False
{ $$ = buildTree(False, NULL, NULL, NULL); }
| sum relation sum
{ $$ = buildTree($1, $2, $3, NULL); }
;
relation
: Less
{ $$ = buildTree(Less, NULL, NULL, NULL); }
| LessEq
{ $$ = buildTree(LessEq, NULL, NULL, NULL); }
| Great
{ $$ = buildTree(Great, NULL, NULL, NULL); }
| GreatEq
{ $$ = buildTree(GreatEq, NULL, NULL, NULL); }
| Eq
{ $$ = buildTree(Eq, NULL, NULL, NULL); }
| NotEq
{ $$ = buildTree(NotEq, NULL, NULL, NULL); }
;
bsecond
: brel
{ $$ = $1; }
| Not brel
{ $$ = buildTree(Not, $2, NULL, NULL); }
;
bfactor
: bsecond
{ $$ = $1; }
| bfactor And bsecond
{ $$ = buildTree(And, $1, NULL, NULL); $$->next = $3; }
;
bterm
: bfactor
{ $$ = $1; }
| bterm Or bfactor
{ $$ = buildTree(Or, $1, NULL, NULL); $$->next = $3; }
;
expr
: bterm
{ $$ = $1; }
| If expr Then bterm Else expr
{ $$ = buildTree(If, $2, $4, $6); }
;
a_expr
: sum
{ $$ = $1; }
| If expr Then sum Else a_expr
{ $$ = buildTree(If, $2, $4, $6); }
;
%%
The lex file:
%{
#include <stdlib.h>
#include <stdio.h>
#include "y.tab.h"
#include "tree.h"
int line_num = 1, position = 1;;
%}
L [A-Za-z]
I [0-9]
R [0-9][0-9]*\.[0-9][0-9]
%%
^".C".* /* comment */;
[ \t]+ position += yyleng;
"and" { position += 3; return And; }
"array" { position += 5; return Array; }
"begin" { position += 5; return Begin; }
"boolean" { position += 7; return Boolean; }
"div" { position += 3; return Div; }
"do" { position += 2; return Do; }
"else" { position += 4; return Else; }
"end" { position += 3; return End; }
"false" { position += 5; return False; }
"for" { position += 3; return For; }
"goto" { position += 4; return Goto; }
"if" { position += 2; return If; }
"imply" { position += 5; return Imply; }
"integer" { position += 7; return Integer; }
"label" { position += 5; return Label; }
"not" { position += 3; return Not; }
"or" { position += 2; return Or; }
"own" { position += 3; return Own; }
"procedure" { position += 9; return Procedure; }
"real" { position += 4; return Real; }
"step" { position += 4; return Step; }
"string" { position += 6; return String; }
"then" { position += 4; return Then; }
"true" { position += 4; return True; }
"until" { position += 5; return Until; }
"value" { position += 5; return Value; }
"while" { position += 5; return While; }
{L}({L}|{I})* { position += yyleng; yylval.i = lookup (yytext); return Ident; }
{I}+ { position += yyleng; yylval.i = atoi (yytext); return IntConst; }
{R}* { position += yyleng; yylval.f = atof (yytext); return RealConst; }
"+" { position += 1; return Plus; }
"-" { position += 1; return Minus; }
"*" { position += 1; return Mult; }
"/" { position += 1; return Div; }
"<" { position += 1; return Less; }
"<=" { position += 2; return LessEq; }
">" { position += 1; return Great; }
">=" { position += 2; return GreatEq; }
"=" { position += 1; return Eq; }
"!=" { position += 2; return NotEq; }
"," { position += 1; return Comma; }
":" { position += 1; return Colon; }
";" { position += 1; return Semi; }
"(" { position += 1; return LParan; }
")" { position += 1; return RParan; }
"[" { position += 1; return LBrak; }
"]" { position += 1; return RBrak; }
":=" { position += 2; return Assign; }
"\n" { line_num++; position = 1; newline(); }
. { position += 1; yyerror ("Bad Character"); }
%%
int yyerror (char strg[]) {
printf("Error: %s at line %d, position %d, token %s\n", strg, line_num, position, yytext);
}
typedef char name[20];
static char Names[200][20] = { "<no name>" };
int top = 0;
int lookup (char strg[]) {
int i;
for (i = 0; i <= top; i++)
if (strcmp (strg, Names[i]) == 0) return i;
strcpy (Names[++top], strg);
return top;
}
void printNames (void) {
int i = 0;
for (; i <= top; i++)
printf("%d\t%strg\n", i, Names[i]);
}
char *id_name (int i) {
return Names[i];
}
The tree.c:
#include <stdio.h>
#include "tree.h"
#include "y.tab.h"
tree buildTree (int kind, tree one, tree two, tree three)
{
tree t = (tree)malloc(sizeof (node));
t->kind = kind;
t->first = one;
t->second = two;
t->third = three;
t->next = NULL;
return t;
}
tree buildIntTree (int kind, int val)
{
tree t = (tree)malloc(sizeof (node));
t->kind = kind;
t->value = val;
t->first = t->second = t->third = NULL;
t->next = NULL;
return t;
}
tree buildFloatTree (int kind, float f_val)
{
tree t;
t->kind = kind;
t->value = f_val;
t->first = t->second = t->third = NULL;
t->next = NULL;
return t;
}
char TokName[][12] =
{"<eof>",
"Ident", "IntConst", "", "", "", "", "", "", "", "",
"IF", "THEN", "END", "WHILE", "DO", "ELSE", "", "", "", "",
"=", "(", ")", "+", "-", "*", "/", ".EQ.", ".NE.", ".LT.",
".LE.", ".GT.", ".GE.", "<eoln>", "+", "-", "", "", "", "",
"<NoType>", "<IntType>", "<BoolType>", "<Prog>", "<Comma>"};
static int indent = 0;
void printTree (tree t)
{
if (t == NULL) return;
for (; t != NULL; t = t->next) {
printf ("%*s%s", indent, "", TokName[t->kind]);
switch (t->kind) {
case Ident:
printf (" %s (%d)\n", id_name (t->value), t->value);
break;
case IntConst:
printf (" %d\n", t->value);
break;
default:
printf ("\n");
indent += 2;
printTree (t->first);
printTree (t->second);
printTree (t->third);
indent -= 2;
}
}
}
The tree.h:
ypedef struct Node {
int kind, value;
float f_val;
struct Node *first, *second, *third, *next;
} node;
typedef node *tree;
extern char TokName[][12];
tree buildTree (int kind, tree first, tree second, tree third);
tree buildIntTree (int kind, int val);
tree buildFloatTree (int kind, float f_val);
void printTree (tree);
And lastly main.c:
#include <stdio.h>
#include "tree.h"
extern FILE *yyin;
extern int yydebug;
tree root;
FILE *outfile;
main (int argc, char **argv)
{
if (argc != 2) {
fprintf (stderr, "%s: Insufficient Arguments\n", argv[0]);
exit(1);
}
// if ((yyin = freopen (argv[1], "r", yyin)) == 0L) {
if ((yyin = fopen (argv[1], "r")) == 0L) {
fprintf (stderr, "%s: Can't open Input File %s\n", argv[0], argv[1]);
exit(1);
}
yyparse();
printTree (root);
close (yyin);
}
Upvotes: 0
Views: 623
Reputation: 126120
Your scanner program (lex file) needs to have #include "tree.h"
before #include "y.tab.h"
-- swap those two lines and it should compile.
Upvotes: 1