Error: "expected identifier or '(' before '%' token" (Csimple parser in yacc) - yacc

im trying to build a compiler for Csimple. when i run the command
"cc –o test y.tab.c –ll –L.y" i get a wall of errors.
i am at a loss.
im aware that my yacc file doesnt parse well,
but first i need it to run so i can see the output.
the error appears for the line "%{" in the middle of the yacc file.
lex:
%option yylineno
%pointer
%{
#include <stdlib.h>
#include <string.h>
void yyerror(const char *);
%}
low \_
identifier {letters}{digit}*{low}{letters}|{letters}
stringERR {doubleQuotes}{doubleQuotes}+|{doubleQuotes}
charERR {singleQuotes}+{digits}*{letters}*{singleQuotes}+
ERR {charERR}|{stringERR}
type boolean|string|char|integer|intptr|charptr|var
dbland "&&"
devide "/"
assign "="
equal "=="
greater ">"
lesser "<"
greaterequal ">="
lesserequal "<="
minus "-"
plus "+"
not "!"
notequal "!="
or "||"
multiply "*"
power "^"
AND "&"
literBool true|false
letter [a-z]|[A-Z]
letters {letter}+
singleQuotes '
literChar {singleQuotes}{letter}{singleQuotes}
digit [0-9]
digitZero 0
octalDigit [1-7]
octal {digitZero}{octalDigit}{digitZero}*{octalDigit}*
digits {digit}+
digitNoZero[1-9]
decimal {digit}|{digitNoZero}{digits}
hexLetter A|B|C|D|E|F
hex 0(x|X){digit}+{hexLetter}*|0(x|X){digit}*{hexLetter}+
letterB b
digitOne 1
binaryInt ({digitZero}|{digitOne})+{letterB}
integer {binaryInt}|{hex}|{octal}|{decimal}
doubleQuotes \"
ltrlString {doubleQuotes}{letters}*{decimal}*{hex}*{octal}*{binaryInt}*{dbland}*{devide}*{assign}*{equal}*{greater}*{lesser}*{greaterequal}*{lesserequal}*{minus}*{plus}*{not}*{notequal}*{or}*{multiply}*{AND}*{power}*{doubleQuotes}
comment {backslash}{parcent}{space}*({letters}*{space}*{identifier}*{space}*{decimal}*{space}*{hex}*{space}*{octal}*{space}*{binaryInt}*{space}*{dbland}*{devide}*{assign}*{equal}*{greater}*{lesser}*{greaterequal}*{lesserequal}*{minus}*{p$us}*{plus}*{not}*{notequal}*{or}*{multiply}*{AND}*{power}*{ltrlString}*)*{space}{parcent}{backslash}
colon ":"
openSq "["
closeSq "]"
semicolon ";"
parcent "%"
space " "
comma ","
backslash "/"
clos ")"
opn "("
charptr charptr
pointer {colon}{space}{charptr}|"="{space}"&"{identifier}
pointerErr "&"{identifier}|{charptr}
ELSE "else"{space}*
statif "if"{space}*
whileLoop "while"{space}*
returnState "return"{space}*
func "procedure"{space}*
%%
{dbland} return dbland;
{devide} return devide;
{assign} return assign;
{equal} return equal;
{greater} return greater;
{greaterequal} return greaterequal;
{lesserequal} return lesserequal;
{minus} return minus;
{plus} return plus;
{not} return not;
{notequal} return notequal;
{or} return or;
{multiply} return multiply;
{power} return power;
{AND} return AND;
{literBool} return literBool;
{literChar} return literChar;
{decimal} return decimal;
{hex} return hex;
{octal} return octal;
{binaryInt} return binaryInt;
{ltrlString} return ltrlString
{type} return type;
{identifier} return identifier;
{ERR} return ERR;
{comment} return comment;
{pointer} return pointer;
{pointerErr} return pointerErr;
{statif} return statif;
{ELSE} return ELSE;
{whileLoop} return whileLoop;
{returnState} return returnState;
{func} return func;
{semicolon} return semicolon;
{comma} return comma;
[\*\(\)\.\+\-\%] { return *yytext; }
[0-9][0-9]* { return 'n'; }
[ \t\n] ; /* skip whitespace */
%%
int yywrap(void) {
return 1;
}
yacc:
%token low identifier stringERR charERR ERR type operator literBool letter
%token dbland literChar decimal hex octal integer
%token binaryInt ltrString comment pointer pointerErr
%token statif ELSE whileLoop returnState func comma semicolon
%token EOL LPAREN RPAREN UMINUS
%left equal greater notequal lesser greaterequal lesserequal
%left '|' %left '&' %left SHIFT /* << >> */
%left minus plus
%left multiply devide '%' MOD %left power
%left not or AND comma
%nonassoc UMINUS
%%
s: BLOCK;
BLOCK: expr|logicOp|varible_declaration|ifExp|whileExp|procExp|semicolon;
expr: exp{printtree($1);}
exp:
identifier {$$=mknode(yytext,NULL,NULL);}
| LPAREN expr RPAREN {$$=$2;}
| exp plus exp {$$= mknode("+" $1,$3);}
| exp minus exp {$$= mknode("-" $1, $3);}
| exp multiply exp {$$=mknode("*" $1, $3);}
| exp devide exp {$$=mknode("/" $1, $3);}
| "-" exp %prec UMINUS {-$2}
varible_declaration: var{printtree($1);}
var : "VAR" identifier_list ":" typet ";" {$$ = mknode("var", $2, $4);}
typet:
integer{$$ = mknode(yytext,NULL,NULL);}
|binaryInt {$$ = mknode(yytext,NULL,NULL);}
|type {$$ = mknode(yytext,NULL,NULL);}
identifier_list: identifier_list comma identifier_list
{$$= mknode(",",$1, $3);}
|identifier {$$ = mknode(yytext,NULL,NULL);}
logicOp: op{printtree($1);}
op:exp equal exp {$$ = mknode("==",$1,$3);}
|exp notequal exp {$$ = mknode("!=",$1,$3);}
|exp or exp {$$ = mknode("||",$1,$3);}
|exp AND exp {$$ = mknode("&&",$1,$3);}
|exp greater exp {$$ = mknode(">",$1,$3);}
|exp greaterequal exp {$$ = mknode(">=",$1,$3);}
|exp lesser exp {$$ = mknode("<",$1,$3);}
|exp lesserequal exp {$$ = mknode("<=",$1,$3);}
ifExp: if{printtree($1);}
if:statif '(' logicOp ')' '{' BLOCK '}' ELSE '{' BLOCK '}' {$$ = mknode("if",$3,mknode("else",$6,$10));}
|statif '(' logicOp ')' '{' BLOCK '}' {$$=mknode("if",$3,$6);}
whileExp: while{printtree($1)}
while:whileLoop '(' logicOp ')' '{' BLOCK '}' {$$=mknode("while",$3,$6);}
procExp: proc{printtree($1)}
proc:func identifier '(' identifier_list ')' returnState type '{' BLOCK '}' {$$ = mknode("procedure",$2,"TODO");}
%%
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define YYDEBUG 1
int yylex(void);
void yyerror(const char *);
tyepdef struct node{char * token;
struct node *left;
struct node *right;
}node;
node * mknode(char * token , node * left,node * right);
void printtree(node * tree);
%}
#define yySType struct node *
#include "lex.yy.c"
main()
{ return yyparse(); }
nose * mknode(char * token,node * left, node * right)
{
node * newnode = (node*)malloc(sizeof(node));
char 8 newstr = (char*)malloc(sizeof(token)+1);
strcpy("newstr,token");
newnode->left=left;
newnode->right=right;
newnode->token=newstr;
}return newnode;
void printtree(node * tree)
{
printf("%s\n",tree->token);
if (tree->left) printtree(tree->left);
if (tree->right) printtree(tree->left);
}
extern int yylineno;
void yyerror(const char *s)
{
fprintf(stderr, "%s at line %d\n", s, yylineno);
return;
}
executes:
lex test.l
yacc test.y
cc –o test y.tab.c –ll –L.y
this is where it all breaks down.
as i said, i get ALOT of errors, but the first one is
test.y:60: error: expected identifier or ‘(’ before ‘%’ token

Yacc directives like %{ can only appear in the FIRST section of the yacc file (before the first %%), with the exception of a few that can be in the second (before the second %%). The third section (after the second %%) is just copied verbatim to the output y.tab.c file, so there can't be anything except C code in it.
It looks like you just want that code in the output, so just delete those %{ and %} lines in the third section. Then, just go through each error or warning you get from the compiler (and do use -Wall) and figure out what they say and how to fix them.

Related

Yacc parser not detecting my language well

I am new to yacc and I am trying to define some rules for my language.
I have written a grammar "well" and it runs and executes without an error but for some reason, it doesn't do what it is supposed to do.
mylex.l
%{
#include <stdio.h>
#include "myyacc.tab.h"
extern int yyval;
%}
/* KEEP TRACK OF LINE NUMBER*/
%option yylineno
uppercase [A-Z]
lowercase [a-z]
alpha [{uppercase}{lowercase}]
digit [0-9]
alphanum [{alpha}{digit}]
id uppercase({alphanum}|_)*
int_literal [0-9]+
float_literal [0-9]+\.[0-9]+
string_literal \"[^\"]*\"
comment (##)(.)*(##)
%%
"int" {return INT;}
"float" {return FLOAT;}
"boolean" {return BOOLEAN;}
"if" {return IF;}
"else" {return ELSE;}
"end" {return END;}
"true" {return TRUE;}
"false" {return FALSE;}
"read" {return READ;}
"print" {return PRINT;}
"while" {return WHILE;}
"START" {return START;}
"END" {return END;}
"+" {return ADD;}
"-" {return SUB;}
"*" {return MUL;}
"/" {return DIV;}
"&&" {return LOG_AND;}
"||" {return LOG_OR;}
"!" {return LOG_NOT;}
"==" {return EQ;}
"<>" {return NEQ;}
"<" {return LT;}
"<=" {return LEQ;}
">" {return GT;}
">=" {return GEQ;}
"=" {return ASSIGN;}
"(" {return LPAREN;}
")" {return RPAREN;}
"{" {return LBRACE;}
"}" {return RBRACE;}
{int_literal} {return INT_LITERAL;}
{float_literal} {return FLOAT_LITERAL;}
{string_literal} {return STRING_LITERAL;}
{id} {return ID;}
{comment} { ; }
%%
int yywrap() {
return 1;
}
myyacc.y
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylineno;
extern FILE* yyin;
extern int yyerror (char* msg);
extern char * yytext;
%}
/* definitions section start */
%token INT FLOAT BOOLEAN IF ELSE END TRUE FALSE READ PRINT WHILE START
%token INT_LITERAL FLOAT_LITERAL STRING_LITERAL ID ERROR
%right ASSIGN
%right LOG_NOT
%left MUL DIV
%left ADD SUB
%left LPAREN RPAREN
%left LBRACE RBRACE
%left LT LEQ GT GEQ
%left EQ NEQ
%left LOG_AND
%left LOG_OR
%start program
/* definitions section end */
%%
/* rules section start */
program : START statements END {printf("No syntax errors detected")};
statements : statements statement
| statement
;
statement : dec_stmt
| assignment_stmt
| print_stmt
| read_stmt
| condition_stmt
| while_stmt
;
dec_stmt : type ID
;
type : INT
| FLOAT
| BOOLEAN
;
assignment_stmt : ID ASSIGN expression
;
expression : exp EQ exp
| exp NEQ exp
| exp LT exp
| exp LEQ exp
| exp GT exp
| exp GEQ exp
| exp
;
exp : exp MUL exp
| exp DIV exp
| exp ADD exp
| exp SUB exp
| exp LOG_AND exp
| exp LOG_OR exp
| LOG_NOT exp
| LPAREN exp RPAREN
| INT_LITERAL
| FLOAT_LITERAL
| ID
| TRUE
| FALSE
;
print_stmt : PRINT LPAREN ID RPAREN
| PRINT LPAREN STRING_LITERAL RPAREN
;
read_stmt : ID ASSIGN READ LPAREN RPAREN
;
condition_stmt : IF LPAREN expression RPAREN LBRACE statement RBRACE END
| IF LPAREN expression RPAREN LBRACE statement RBRACE ELSE LBRACE statement RBRACE END
;
while_stmt : WHILE LPAREN expression RPAREN LBRACE statement RBRACE
;
/* rules section end */
%%
/* auxiliary routines start */
int main(int argc, char *argv[])
{
// don't change this part
yyin = fopen(argv[1], "r" );
if(!yyparse())
printf("\nParsing complete\n");
else
printf("\nParsing failed\n");
fclose(yyin);
return 0;
}
int yyerror (char* msg)
{
printf("Line %d: %s near %s\n", yylineno, msg, yytext);
exit(1);
}
/* auxiliary routines end */
Test case
START
int X12
float ABC1
DDe = 7
while(QNn >0) ## this a Comment ##
{ RLk9999 = ACc - 2
CCC = true
}
if ( ACc ==5){ print ( " Inside IF inside Loop " ) } end }
print ( " Hello .. " )
END
Output
Line 3: syntax error near 12
It also gets the line number wrong.
I've been trying to see what I'm doing wrong for some time now and I'd really appreciate a second set of eyes.
You cannot use macros inside character classes. Inside a character class, pattern operators lose their special meaning, so when you write
alphanum [{alpha}{digit}]
you are defining a character class containing {, }, and the letters adghilpt. That doesn't match the 12 in X12.
Anyway, flex already has predefined sets of characters which you can include in your character classes:
* [:lower:] a-z
* [:upper:] A-Z
* [:alpha:] [:lower:][:upper:]
* [:digit:] 0-9
* [:alnum:] [:alpha:][:digit:]
Note that these can only be used inside a character class. So you could write your id pattern as
id [[:upper:]][[:alnum:]_]*
without the need for any other macros.
Please see the flex pattern documentation for more details.
In addition to #rici's answer, I've also noticed that my while_statement in the yacc file has only been set to accept only one statement in it's body

reduce/ reduce conflict - yacc (identifier)

I'm trying to write parser for c simple. The error I get is : "reduce /reduce conflict"
1) Rule exp need to get to IDENTIFIER
for example: a-b(identifier-identifier)-> exp-exp->exp
2) Rule ident_list also need to get to IDENTIFIER . This rule is used for variable declaration.
for example: a,b,c(identifier,identifier,identifier)-> ident_list .
Therefor i need both of rules, ident_list and exp to go to ->IDENTIFIER .This is causing the "reduce /reduce conflict". Any idea how to solve this?
-------------*yac code*:---------------
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char* token;
struct node* left;
struct node* right;
char* type;
}node;
typedef struct obj
{
char* type;
char* name;
struct obj* next;
}obj;
typedef struct symTbl
{
struct obj* first;
struct obj* last;
int size;
}symTbl;
node* mknode (char* token,node* left, node* right,char* Type);
void put(symTbl* tbl, char* type,char* name);
void printtree(node* tree);
#define YYSTYPE struct node*
%}
%start s
%token WHILELOOP
%token STATIF
%token ELSE
%token MAIN
%token POINTERERR
%token COMMENT
%token POINTER
%token GREATEREQUAL
%token LESSEREQUAL
%token DBLAND
%token GREATER
%token LESSER
%token POWER
%token MULTIPLY
%token MINUS
%token PLUS
%token AND
%token OR
%token NOT
%token NOTEQUAL
%token CHARERROR
%token STRINGERROR
%token POINTER
%token INTEGER
%token BOOLEAN
%token DEVIDE
%token ASSIGN
%token EQUAL
%token TYPE
%token IDENTIFIER
%token HEX IF
%token LITERCHAR
%token OCTAL
%token BINARYINT
%token LTRLSTRING
%token COMMA COLON SEMICOLON VAR RETURN RPARENC LPARENC
%left COMMA LPAREN RPAREN ELSE
%left PLUS IF WHILELOOP TYPE
%left MINUS DEVIDE RPARENC LPARENC
%left MULTIPLY EQUAL NOTEQUAL OR AND LESSEREQUAL GREATEREQUAL GREATER LESSER
%%
s:progrem{printtree($1);}
progrem:exp|var_dec|if_stnt|ident_list|bool_exp| mul_ident;
exp: exp PLUS exp{$$=mknode("+",$1,$3,"arit");}
|exp MINUS exp {$$=mknode("-",$1,$3,"arit");}
|exp DEVIDE exp {$$=mknode("/",$1,$3,"arit");}
|exp MULTIPLY exp {$$=mknode("*",$1,$3,"arit");}
|MINUS exp {$$=mknode("-",$2,NULL,"arit");}
|IDENTIFIER {$$=mknode(yytext,NULL,NULL,"id");}
|LPAREN exp RPAREN {$$= $2;};
bool_exp : exp EQUAL exp {$$=mknode("=",$1,$3,"bool");}
|exp NOTEQUAL exp {$$=mknode("!=",$1,$3,"bool");}
|exp OR exp {$$=mknode("||",$1,$3,"bool");}
|exp AND exp {$$=mknode("&&",$1,$3,"bool");}
|exp GREATEREQUAL exp {$$=mknode(">=",$1,$3,"bool");}
|exp LESSER exp {$$=mknode("<",$1,$3,"bool");}
|exp LESSEREQUAL exp {$$=mknode("<=",$1,$3,"bool");}
|exp GREATER exp {$$=mknode(">",$1,$3,"bool");}
|LPAREN bool_exp RPAREN {$$= $2;};
var_dec:ident_list COLON ident_list {$$=mknode(":",$1,$3,"dec");};
ident_list: ident_list COMMA ident_list {$$=mknode(",", $1, $3,"id_list");}
|ident_list TYPE ident_list{$$=mknode(yytext,$1,NULL,"id");}
|VAR {$$= mknode("var",NULL,NULL,"id");}
|SEMICOLON {$$= mknode(";",NULL,NULL,"id");};
|IDENTIFIER {$$=$1;}
if_stnt:IF LPAREN bool_exp RPAREN {$$=mknode("if",$3,NULL,"if_state");};
%%
#include "lex.yy.c"
main()
{
yyin=fopen("text.txt","r");
return yyparse();
}
node* mknode( char* token,node*left,node* right,char* Type)
{
node* newnode=(node*)malloc(sizeof(node));
char* newstr=(char*)malloc(sizeof(token)+1);
char* type = (char*)malloc (sizeof(Type)+1);
type[sizeof(token)]='\0';
newstr[sizeof(token)]='\0';
strcpy(newstr,token);
strcpy(type,Type);
newnode->left=left;
newnode->type=type;
newnode->right=right;
newnode->token=newstr;
return newnode;
}
void put(symTbl* tbl, char* type,char* name)
{
symTbl* tbl1=(symTbl*)malloc(sizeof(symTbl));
int size = tbl->size;
obj* newobj=(obj*)malloc(sizeof(obj));
newobj= tbl->first;
int i;
for( i =0; i<size; i++){
if(newobj->name == name){
yyerror();
newobj=newobj->next;
}
}
tbl->last->next=newobj;
tbl->last=tbl->last->next;
}
void printtree(node* tree)
{
printf("%s",tree->token);
if(tree->left)printtree(tree->left);
if(tree->right)printtree(tree->right);
}
int yyerror()
{
printf("bla bla\n");
return 0;
}
--------lex code:------------
minus "-"
colon ":"
semicolon ";"
space " "
parcent "%"
backslash "/"
charptr charptr
plus "+"
not "!"
notequal "!="
or "||"
and "&&"
multiply "*"
power "^"
dbland "&"
greater ">"
lesser "<"
type boolean|string|char|integer|intptr|charptr
return "return"
greaterequal {greater}{assign}
lesserequal {lesser}{assign}
singleQuotes \'
charERR {singleQuotes}+(({digit})+)*(({letter})+)*{singleQuotes}+
stringERR {doubleQuotes}{doubleQuotes}+|{doubleQuotes}
doubleQuotes \"
var "var"{space}*
octalDigit [1-7]
decimal {digit}|{digitNoZero}{digit}+
digitNoZero[1-9]
octal "0"{octalDigit}("0")*{octalDigit}*
integer {binaryInt}|{hex}|{octal}|{decimal}
binaryInt ("0"|"1")+"b"
hexLetter A|B|C|D|E|F
hex 0(x|X){digit}+{hexLetter}*|0(x|X){digit}*{hexLetter}+
literBool true|false
letter [a-zA-Z]
letters {letter}+
digit [0-9]
low "_"
equal "=="
assign "="
devide "/"
lparen "("
rparen ")"
lparenc "{"
rparenc "}"
identifier {letter}+{digit}*{letter}+{space}*|{space}*{letter}{space}*
literChar {singleQuotes}{letter}{singleQuotes}
ltrlString {doubleQuotes}{letters}*{decimal}*{hex}*{octal}*{binaryInt}*{dbland}*{devide}*{assign}*{equal}*{greater}*{lesser}*{greaterequal}*{lesserequal}*{mi$
pointer {colon}{space}{charptr}|"="{space}"&"{identifier}
comment {backslash}{parcent}{space}*({letters}*{space}*{identifier}*{space}*{decimal}*{space}*{hex}*{space}*{octal}*{space}*{binaryInt}*{space}*{dbland}*{dev$
pointerErr "&"{identifier}|{charptr}
statif "if"{space}*
ELSE "else"{space}*
comma ","
whileLoop "while"{space}*
main "main"
%%
{lparen} return LPAREN;
{rparen} return RPAREN;
{colon} return COLON;
{type} return TYPE;
{semicolon} return SEMICOLON;
{var} return VAR;
{whileLoop} return WHILELOOP;
{ELSE} return ELSE;
{statif} return IF;
{pointerErr} return POINTERERR;
{comment} return COMMENT;
{pointer} return POINTER;
{literChar} return LITERCHAR;
{charERR} return CHARERROR;
{stringERR} return STRINGERROR;
{ltrlString} return LTRLSTRING;
{binaryInt} return BINARYINT;
{octal} return OCTAL;
{hex} return HEX;
{return} return RETURN;
{greaterequal} return GREATEREQUAL;
{lesserequal} return LESSEREQUAL;
{dbland} return DBLAND;
{greater} return GREATER;
{lesser} return LESSER;
{lparenc} return LPARENC;
{rparenc} return RPARENC;
{power} return POWER;
{multiply} return MULTIPLY;
{plus} return PLUS;
{or} return OR;
{and} return AND;
{comma} return COMMA;
{not} return NOT;
{main} return MAIN;
{notequal} return NOTEQUAL;
{minus} return MINUS;
{integer} return INTEGER;
{literBool} return BOOLEAN;
{identifier} return IDENTIFIER;
{equal} return EQUAL;
{assign} return ASSIGN;
{devide} return DEVIDE;
. return yytext[0];
You're saying that a program can be either an exp or an ident_list, among other things. This is not particularly sensible to start with, and I suppose your intention is to do some sort of debugging. But it is not going to work because a single identifier could be an expression or a list containing exactly one identifier, and there is no obvious way for the parser to guess which one you meant. That makes your grammar ambiguous.
What yacc/bison does in this case is to choose whichever production comes earlier in the grammar file. That's not a very precise way of defining a preference, so it warns you about the conflict. But it makes it possible for you to express your preference.
Otherwise, you'd have to eliminate the ambiguity. If, for example, you decided that a single identifier should be an exp, you could insist that a top-level identifier list have at least two identifiers.

yacc do not printing AST

edit my question.
in expression rule: exp does not reduced to expression
for example: identifier(exp)-identifier(exp)
run test: http://www.interload.co.il/upload/2528784.png
in the image you can see that yacc is waiting for more input for some reason.
what is wrong with expression rule?
-----------------------------yacc code-------------------------------
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
char* token;
struct node* left;
struct node* right;
}node;
node* mknode(char* token,node* left, node* right);
void printtree(node* tree);
#define YYSTYPE struct node*
%}
%start s
%token WHILELOOP
%token STATIF
%token ELSE
%token MAIN
%token POINTERERR
%token COMMENT
%token POINTER
%token GREATEREQUAL
%token LESSEREQUAL
%token DBLAND
%token GREATER
%token LESSER
%token LESSER
%token POWER
%token MULTIPLY
%token MINUS
%token PLUS
%token AND
%token OR
%token NOT
%token NOTEQUAL
%token CHARERROR
%token STRINGERROR
%token POINTER
%token INTEGER
%token BOOLEAN
%token DEVIDE
%token ASSIGN
%token EQUAL
%token TYPE
%token IDENTIFIER
%token HEX IF
%token LITERCHAR
%token OCTAL
%token BINARYINT
%token LTRLSTRING
%token COMMA COLON SEMICOLON VAR RETURN RPARENC LPARENC
%left COMMA LPAREN RPAREN
%left PLUS
%left MINUS DEVIDE
%left MULTIPLY EQUAL NOTEQUAL OR AND LESSEREQUAL GREATEREQUAL GREATER LESSER
%right IDENTIFIER
%%
s: expression|operator|var_declare|if_stnt;
{
printf("blaAA bla/n");
};
expression: exp {printtree($1);}
exp: exp PLUS exp {$$=mknode("+",$1,$3);}
|exp MINUS exp {$$=mknode("-",$1,$3);}
|exp DEVIDE exp {$$=mknode("/",$1,$3);}
|exp MULTIPLY exp {$$=mknode("*",$1,$3);}
| MINUS exp {$$=mknode("-",NULL,$2);}
|IDENTIFIER {$$= mknode(yytext,NULL,NULL);}
operator: op{printtree($1);}
op: exp EQUAL exp {$$=mknode("=",$1,$3);}
|exp NOTEQUAL exp {$$=mknode("!=",$1,$3);}
|exp OR exp {$$=mknode("||",$1,$3);}
|exp AND exp {$$=mknode("&&",$1,$3);}
|exp GREATER exp {$$=mknode(">",$1,$3);}
|exp GREATEREQUAL exp {$$=mknode(">=",$1,$3);}
|exp LESSER exp {$$=mknode("<",$1,$3);}
|exp LESSEREQUAL exp {$$=mknode("<=",$1,$3);}
var_declare: var {printtree($1);}
var: VAR ident_list COLON TYPE SEMICOLON{$$=mknode("var",$2,$4);}
ident_list: ident_list COMMA ident_list {$$=mknode(",", $1, $3);}
|IDENTIFIER {$$= mknode(yytext,NULL,NULL);}
if_stnt:IF LPAREN exp RPAREN
%%
#include "lex.yy.c"
main()
{
return yyparse();
}
node* mknode(char* token,node*left,node* right)
{
node* newnode=(node*)malloc(sizeof(node));
char* newstr=(char*)malloc(sizeof(token)+1);
newstr[sizeof(token)]='\0';
strcpy(newstr,token);
newnode->left=left;
newnode->right=right;
newnode->token=newstr;
return newnode;
}
void printtree(node* tree)
{
printf("%s\n",tree->token);
if(tree->left)printtree(tree->left);
if(tree->right)printtree(tree->right);
}
int yyerror()
{
printf("bla bla\n");
return 0;
}
---------------lex code:--------------------------------
minus "-"
colon ":"
semicolon ";"
space " "
parcent "%"
backslash "/"
charptr charptr
plus "+"
not "!"
notequal "!="
or "||"
and "&&"
multiply "*"
power "^"
dbland "&"
greater ">"
lesser "<"
return "return"
greaterequal {greater}{assign}
lesserequal {lesser}{assign}
singleQuotes \'
charERR {singleQuotes}+(({digit})+)*(({letter})+)*{singleQuotes}+
stringERR {doubleQuotes}{doubleQuotes}+|{doubleQuotes}
doubleQuotes \"
octalDigit [1-7]
decimal {digit}|{digitNoZero}{digit}+
digitNoZero[1-9]
octal "0"{octalDigit}("0")*{octalDigit}*
integer {binaryInt}|{hex}|{octal}|{decimal}
binaryInt ("0"|"1")+"b"
hexLetter A|B|C|D|E|F
hex 0(x|X){digit}+{hexLetter}*|0(x|X){digit}*{hexLetter}+
literBool true|false
letter [a-zA-Z]
letters {letter}+
digit [0-9]
low "_"
equal "=="
assign "="
devide "/"
lparen "("
rparen ")"
lparenc "{"
rparenc "}"
identifier {letter}+{digit}*{letter}+|{letter}
type boolean|string|char|integer|intptr|charptr|var
literChar {singleQuotes}{letter}{singleQuotes}
ltrlString {doubleQuotes}{letters}*{decimal}*{hex}*{octal}*{binaryInt}*{dbland}*$
pointer {colon}{space}{charptr}|"="{space}"&"{identifier}
comment {backslash}{parcent}{space}*({letters}*{space}*{identifier}*{space}*{dec$
pointerErr "&"{identifier}|{charptr}
statif "if"{space}*
ELSE "else"{space}*
comma ","
whileLoop "while"{space}*
main "main"
var "VAR"
%%
{lparen} return LPAREN;
{rparen} return RPAREN;
{colon} return COLON;
{semicolon} return SEMICOLON;
{var} return VAR;
{whileLoop} return WHILELOOP;
{ELSE} return ELSE;
{statif} return IF;
{pointerErr} return POINTERERR;
{comment} return COMMENT;
{pointer} return POINTER;
{literChar} return LITERCHAR;
{charERR} return CHARERROR;
{stringERR} return STRINGERROR;
{ltrlString} return LTRLSTRING;
{binaryInt} return BINARYINT;
{octal} return OCTAL;
{hex} return HEX;
{return} return RETURN;
{greaterequal} return GREATEREQUAL;
{lesserequal} return LESSEREQUAL;
{dbland} return DBLAND;
{greater} return GREATER;
{lesser} return LESSER;
{lparenc} return LPARENC;
{rparenc} return RPARENC;
{power} return POWER;
{multiply} return MULTIPLY;
{plus} return PLUS;
{or} return OR;
{and} return AND;
{comma} return COMMA;
{not} return NOT;
{main} return MAIN;
{notequal} return NOTEQUAL;
{minus} return MINUS;
{integer} return INTEGER;
{literBool} return BOOLEAN;
{identifier} return IDENTIFIER;
{equal} return EQUAL;
{assign} return ASSIGN;
{devide} return DEVIDE;
{type} return TYPE;
. return yytext[0];
In order to do the final reduction s: expression and return, yacc needs to see the EOF at the end of the input. If you are reading from a file, that EOF will come automatically, but there is no end to terminal input, so with input coming from a terminal, you'll need to give it an explicit EOF indication by hitting ctrlD (ctrlZ on windows).

Lex Yacc parser compiling get few errors tried searching solution cant find

We have a task to compile a lex and a yacc praser code then run them together by using the cc tab.y.c -ll -Ly command when we do each apart they compile just fine but the compile both parts as one gives 10 lines of errors.
First part is Lex Code:
%option yylineno
%pointer
%{
#include <stdlib.h>
#include <string.h>
void yyerror(const char *);
%}
low \_
identifier {letters}{digit}*{low}{letters}|{letters}
stringERR {doubleQuotes}{doubleQuotes}+|{doubleQuotes}
charERR {singleQuotes}+{digits}*{letters}*{singleQuotes}+
ERR {charERR}|{stringERR}
type boolean|string|char|integer|intptr|charptr|var
dbland "&&"
devide "/"
assign "="
equal "=="
greater ">"
lesser "<"
greaterequal ">="
lesserequal "<="
minus "-"
plus "+"
not "!"
notequal "!="
or "||"
multiply "*"
power "^"
AND "&"
literBool true|false
letter [a-z]|[A-Z]
letters {letter}+
singleQuotes '
literChar {singleQuotes}{letter}{singleQuotes}
digit [0-9]
digitZero 0
octalDigit [1-7]
octal {digitZero}{octalDigit}{digitZero}*{octalDigit}*
digits {digit}+
digitNoZero[1-9]
decimal {digit}|{digitNoZero}{digits}
hexLetter A|B|C|D|E|F
hex 0(x|X){digit}+{hexLetter}*|0(x|X){digit}*{hexLetter}+
letterB b
digitOne 1
binaryInt ({digitZero}|{digitOne})+{letterB}
integer {binaryInt}|{hex}|{octal}|{decimal}
doubleQuotes \"
ltrlString {doubleQuotes}{letters}*{decimal}*{hex}*{octal}*{binaryInt}*{dbland}*{devide}*{assign}*{equal}*{greater}*{lesser}*{greaterequal}*{lesserequal}*{minus}*{plus}*{not}*{notequal}*{or}*{multiply}*{AND}*{power}*{doubleQuotes}
comment {backslash}{parcent}{space}*({letters}*{space}*{identifier}*{space}*{decimal}*{space}*{hex}*{space}*{octal}*{space}*{binaryInt}*{space}*{dbland}*{devide}*{assign}*{equal}*{greater}*{lesser}*{greaterequal}*{lesserequal}*{minus}*{$nus}*{plus}*{not}*{notequal}*{or}*{multiply}*{AND}*{power}*{ltrlString}*)*{space}{parcent}{backslash}
colon ":"
openSq "["
closeSq "]"
semicolon ";"
parcent "%"
space " "
comma ","
backslash "/"
clos ")"
opn "("
charptr charptr
pointer {colon}{space}{charptr}|"="{space}"&"{identifier}
pointerErr "&"{identifier}|{charptr}
ELSE "else"{space}*
statif "if"{space}*
whileLoop "while"{space}*
returnState "return"{space}*
func "procedure"{space}*
%%
{dbland} return dbland;
{devide} return devide;
{assign} return assign;
{equal} return equal;
{greater} return greater;
{lesser} return lesser;
{greaterequal} return greaterequal;
{lesserequal} return lesserequal;
{minus} return minus;
{plus} return plus;
{not} return not;
{notequal} return notequal;
{or} return or;
{multiply} return multiply;
{power} return power;
{AND} return AND;
{literBool} return literBool;
{literChar} return literChar;
{decimal} return decimal;
{hex} return hex;
{octal} return octal;
{binaryInt} return binaryInt;
{ltrlString} return ltrlString
{type} return type;
{identifier} return identifier;
{ERR} return ERR;
{comment} return comment;
{pointer} return pointer;
{pointerErr} return pointerErr;
{statif} return statif;
{ELSE} return ELSE;
{whileLoop} return whileLoop;
{returnState} return returnState;
{func} return func;
{semicolon} return semicolon;
{comma} return comma;
[\*\(\)\.\+\-\%] { return *yytext; }
[0-9][0-9]* { return 'n'; }
[ \t\n] ; /* skip whitespace */
%%
int yywrap(void) {
return 1;
}
yacc code:
%token low identifier stringERR charERR ERR type operator literBool letter
%token dbland literChar decimal hex octal integer
%token binaryInt ltrString comment pointer pointerErr
%token statif ELSE whileLoop returnState func comma semicolon
%token EOL LPAREN RPAREN UMINUS
%left equal greater notequal lesser greaterequal lesserequal
%left '|' %left '&' %left SHIFT /* << >> */
%left minus plus
%left multiply devide '%' MOD %left power
%left not or AND comma
%nonassoc UMINUS
%%
s: BLOCK;
BLOCK: expr|logicOp|varible_declaration|ifExp|whileExp|procExp|semicolon;
expr: exp{printtree($1);}
exp:
identifier {$$=mknode(yytext,NULL,NULL);}
| LPAREN expr RPAREN {$$=$2;}
| exp plus exp {$$= mknode("+" $1,$3);}
| exp minus exp {$$= mknode("-" $1, $3);}
| exp multiply exp {$$=mknode("*" $1, $3);}
| exp devide exp {$$=mknode("/" $1, $3);}
| "-" exp %prec UMINUS {-$2}
varible_declaration: var{printtree($1);}
var : "VAR" identifier_list ":" typet ";" {$$ = mknode("var", $2, $4);}
typet:
integer{$$ = mknode(yytext,NULL,NULL);}
|binaryInt {$$ = mknode(yytext,NULL,NULL);}
|type {$$ = mknode(yytext,NULL,NULL);}
identifier_list: identifier_list comma identifier_list
{$$= mknode(",",$1, $3);}
|identifier {$$ = mknode(yytext,NULL,NULL);}
logicOp: op{printtree($1);}
op:exp equal exp {$$ = mknode("==",$1,$3);}
|exp notequal exp {$$ = mknode("!=",$1,$3);}
|exp or exp {$$ = mknode("||",$1,$3);}
|exp AND exp {$$ = mknode("&&",$1,$3);}
|exp greater exp {$$ = mknode(">",$1,$3);}
|exp greaterequal exp {$$ = mknode(">=",$1,$3);}
|exp lesser exp {$$ = mknode("<",$1,$3);}
|exp lesserequal exp {$$ = mknode("<=",$1,$3);}
ifExp: if{printtree($1);}
if:statif '(' logicOp ')' '{' BLOCK '}' ELSE '{' BLOCK '}' {$$ = mknode("if",$3,mknode("else",$6,$10));}
|statif '(' logicOp ')' '{' BLOCK '}' {$$=mknode("if",$3,$6);}
whileExp: while{printtree($1)}
while:whileLoop '(' logicOp ')' '{' BLOCK '}' {$$=mknode("while",$3,$6);}
procExp: proc{printtree($1)}
proc:func identifier '(' identifier_list ')' returnState type '{' BLOCK '}' {$$ = mknode("procedure",$2,"TODO");}
%%
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex(void);
void yyerror(const char *);
tyepdef struct node{
char * token;
struct node *left;
struct node *right;
};
node * mknode(char * token , node * left,node * right);
void printtree(node * tree);
#define yySType struct node *
#include "lex.yy.c"
main()
{ return yyparse(); }
nose * mknode(char * token,node * left, node * right)
{
node * newnode = (node*)malloc(sizeof(node));
char 8 newstr = (char*)malloc(sizeof(token)+1);
strcpy("newstr,token");
newnode->left=left;
newnode->right=right;
newnode->token=newstr;
}return newnode;
void printtree(node * tree)
{
printf("%s\n",tree->token);
if (tree->left) printtree(tree->left);
if (tree->right) printtree(tree->left);
}
extern int yylineno;
void yyerror(const char *s)
{
fprintf(stderr, "%s at line %d\n", s, yylineno);
return;
}
the errors we get are the following:
[tzurisa#Ac-Aix backup]$ nano test.l
[tzurisa#Ac-Aix backup]$ lex test.l
[tzurisa#Ac-Aix backup]$ yacc test.y
[tzurisa#Ac-Aix backup]$ cc -o test y.tab.c -ll -Ly
test.y:63: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘struct’
test.y:68: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
test.y:69: error: expected ‘)’ before ‘*’ token
In file included from test.y:72:
test.l: In function ‘yylex’:
test.l:74: error: ‘assign’ undeclared (first use in this function)
test.l:74: error: (Each undeclared identifier is reported only once
test.l:74: error: for each function it appears in.)
In file included from test.y:72:
test.l:94: error: ‘ltrlString’ undeclared (first use in this function)
test.l:95: error: expected ‘;’ before ‘break’
test.y: At top level:
test.y:75: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
test.y:83: error: expected identifier or ‘(’ before ‘return’
test.y:84: error: expected ‘)’ before ‘*’ token
test.y: In function ‘yyparse’:
test.y:20: error: expected ‘)’ before ‘yyvsp’
test.y:21: error: expected ‘)’ before ‘yyvsp’
test.y:22: error: expected ‘)’ before ‘yyvsp’
test.y:23: error: expected ‘)’ before ‘yyvsp’
test.y:24: error: expected ‘;’ before ‘}’ token
test.y:51: error: expected ‘;’ before ‘}’ token
test.y:53: error: expected ‘;’ before ‘}’ token
will appriciate the help of anyone who can tell us whats wrong here we have tried many things we still get these errors ..
If you look at line 63 of test.y, as indicated in the first error message, you will see the first problem; you misspelled typedef. Fix that, and then check remaining errors, if any, by looking at the indicated lines.

Bison:syntax error at the end of parsing

Hello this is my bison grammar file for a mini-programming language:
%{
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "projectbison.tab.h"
void yyerror(char const *);
extern FILE *yyin;
extern FILE *yyout;
extern int yylval;
extern int yyparse(void);
extern int n;
int errNum = 0;
int forNum = 0;
%}
%left PLUS MINUS
%left MULT DIV MOD
%nonassoc EQUAL NEQUAL LESS GREATER LEQUAL GEQUAL
%token INTEGER BOOLEAN STRING VOID
%token ID
%token AND
%token BEGINP
%token ENDP
%token EXTERN
%token COMMA
%token EQ
%token RETURN1
%token IF1 ELSE1 WHILE1 FOR1 DO1
%token LOR LAND LNOT
%token TRUE FALSE
%token EQUAL NEQUAL LESS GREATER LEQUAL GEQUAL
%token LB1 RB1
%token LCB1 RCB1
%token SEMIC
%token NEWLINE
%token PLUS MINUS
%token MULT DIV MOD
%token DIGIT STRING1
%start program
%%
/*50*/
program : external-decl program-header defin-field command-field
;
external-decl : external-decl external-prototype
|
;
external-prototype : EXTERN prototype-func NEWLINE
;
program-header : VOID ID LB1 RB1 NEWLINE
;
defin-field : defin-field definition
|
;
definition : variable-defin
| func-defin
| prototype-func
;
variable-defin : data-type var-list SEMIC newline
;
data-type : INTEGER
| BOOLEAN
| STRING
;
var-list : ID extra-ids
;
extra-ids : COMMA var-list
|
;
func-defin : func-header defin-field command-field
;
prototype-func : func-header SEMIC
;
func-header : data-type ID LB1 lists RB1 newline
;
lists: list-typ-param
|
;
list-typ-param : typical-param typical-params
;
typical-params : COMMA list-typ-param
|
;
typical-param : data-type AND ID
;
command-field : BEGINP commands newline ENDP newline
;
commands : commands newline command
|
;
command : simple-command SEMIC
| struct-command
| complex-command
;
complex-command : LCB1 newline command newline RCB1
;
struct-command : if-command
| while-command
| for-command
;
simple-command : assign
| func-call
| return-command
| null-command
;
if-command : IF1 LB1 gen-expr RB1 newline command else-clause
;
else-clause: ELSE1 newline command
;
while-command : WHILE1 LB1 gen-expr RB1 DO1 newline RCB1 command LCB1
;
for-command : FOR1 LB1 conditions RB1 newline RCB1 command LCB1
;
conditions : condition SEMIC condition SEMIC condition SEMIC
;
condition : gen-expr
|
;
assign : ID EQ gen-expr
;
func-call : ID LB1 real-params-list RB1
| ID LB1 RB1
;
real-params-list : real-param real-params
;
real-params : COMMA real-param real-params
|
;
real-param : gen-expr
;
return-command : RETURN1 gen-expr
;
null-command :
;
gen-expr : gen-terms gen-term
;
gen-terms : gen-expr LOR
|
;
gen-term : gen-factors gen-factor
;
gen-factors : gen-term LAND
|
;
gen-factor : LNOT first-gen-factor
| first-gen-factor
;
first-gen-factor : simple-expr comparison
| simple-expr
;
comparison : compare-operator simple-expr
;
compare-operator : EQUAL
| NEQUAL
| LESS
| GREATER
| LEQUAL
| GEQUAL
;
simple-expr : expresion simple-term
;
expresion : simple-expr PLUS
|simple-expr MINUS
|
;
simple-term : mul-expr simple-parag
;
mul-expr: simple-term MULT
| simple-term DIV
| simple-term MOD
|
;
simple-parag : simple-prot-oros
| MINUS simple-prot-oros
;
simple-prot-oros : ID
| constant
| func-call
| LB1 gen-expr RB1
;
constant : DIGIT
| STRING1
| TRUE
| FALSE
;
newline:NEWLINE
|
;
%%
void yyerror(char const *msg)
{
errNum++;
fprintf(stderr, "%s\n", msg);
}
int main(int argc, char **argv)
{
++argv;
--argc;
if ( argc > 0 )
{yyin= fopen( argv[0], "r" ); }
else
{yyin = stdin;
yyout = fopen ( "output", "w" );}
int a = yyparse();
if(a==0)
{printf("Done parsing\n");}
else
{printf("Yparxei lathos sti grammi: %d\n", n);}
printf("Estimated number of errors: %d\n", errNum);
return 0;
}
for a simple input like this :
void main()
integer k;
boolean l;
begin
aek=32;
end
i get the following :
$ ./MyParser.exe file2.txt
void , id ,left bracket , right bracket
integer , id ,semicolon
boolean , id ,semicolon
BEGIN PROGRAM
id ,equals , digit ,semicolon
END PROGRAM
syntax error
Yparxei lathos sti grammi: 8
Estimated number of errors: 1
And whatever change i make to the input file i get a syntax error at the end....Why do i get this and what can i do??thanks a lot in advance!here is the flex file just in case someone needs it :
%{
#include "projectbison.tab.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n=1;
%}
%option noyywrap
digit [0-9]+
id [a-zA-Z][a-zA-Z0-9]*
%%
"(" {printf("left bracket , "); return LB1;}
")" {printf("right bracket\n"); return RB1;}
"{" {printf("left curly bracket , "); return LCB1;}
"}" {printf("right curly bracket\n"); return RCB1;}
"==" {printf("isotita ,"); return EQUAL;}
"!=" {printf("diafora ,"); return NEQUAL;}
"<" {printf("less_than ,"); return LESS;}
">" {printf("greater_than ,"); return GREATER;}
"<=" {printf("less_eq ,"); return LEQUAL;}
">=" {printf("greater_eq ,"); return GEQUAL;}
"||" {printf("lor\n"); return LOR;}
"&&" {printf("land\n"); return LAND;}
"&" {printf("and ,"); return AND;}
"!" {printf("lnot ,"); return LNOT;}
"+" {printf("plus ,"); return PLUS; }
"-" {printf("minus ,"); return MINUS;}
"*" {printf("multiply ,"); return MULT;}
"/" {printf("division ,"); return DIV;}
"%" {printf("mod ,"); return MOD;}
";" {printf("semicolon \n"); return SEMIC;}
"=" {printf("equals , "); return EQ;}
"," {printf("comma ,"); return COMMA;}
"\n" {n++; return NEWLINE;}
void {printf("void ,"); return VOID;}
return {printf("return ,"); return RETURN1;}
extern {printf("extern\n"); return EXTERN;}
integer {printf("integer ,"); return INTEGER;}
boolean {printf("boolean ,"); return BOOLEAN;}
string {printf("string ,"); return STRING;}
begin {printf("BEGIN PROGRAM\n"); return BEGINP;}
end {printf("END PROGRAM\n"); return ENDP;}
for {printf("for\n"); return FOR1;}
true {printf("true ,"); return TRUE;}
false {printf("false ,"); return FALSE;}
if {printf("if\n"); return IF1; }
else {printf("else\n"); return ELSE1; }
while {printf("while\n"); return WHILE1;}
{id} {printf("id ,"); return ID;}
{digit} {printf("digit ,"); return DIGIT;}
[a-zA-Z0-9]+ {return STRING1;}
` {/*catchcall*/ printf("Mystery character %s\n", yytext); }
<<EOF>> { static int once = 0; return once++ ? 0 : '\n'; }
%%
Your scanner pretty well guarantees that two newline characters will be sent at the end of the input: one from the newline present in the input, and another one as a result of your trapping <<EOF>>. However, your grammar doesn't appear to accept unexpected newlines, so the second newline will trigger a syntax error.
The simplest solution would be to remove the <<EOF>> rule, since text files without a terminating newline are very rare, and it is entirely legitimate to consider them syntax errors. A more general solution would be to allow any number of newline characters to appear where a newline is expected, by defining something like:
newlines: '\n' | newlines '\n';
(Using actual characters for single-character tokens makes your grammar much more readable, and simplifies your scanner. But that's a side issue.)
You might also ask yourself whether you really need to enforce newline terminators, since your grammar seems to use ; as a statement terminator, making the newline redundant (aside from stylistic considerations). Removing newlines from the grammar (and ignoring them, as with other whitespace, in the scanner) will also simplify your code.