How to solve yacc error "... has no declared type" - parsing

I have problem on Yacc/Bison.
We use Kotlin grammar.
This is my code :
%token BOOL
%token BREAK
%token CHAR
%token CONTINUE
%token DO
%token ENUM
%token EXTERN
%token FALSE
%token FLOAT
%token FOR
%token FN
%token IN
%token INT
%token LET
%token LOOP
%token MATCH
%token MUT
%token PRINT
%token PRINTLN
%token PUB
%token RETURN
%token SELF
%token STATIC
%token STR
%token STRUCT
%token TRUE
%token USE
%token WHERE
%token IF
%token ELSE
%token <Token> INTEGER
%token <Token> STRING
%token <Token> REAL
%token <Token> ID
%type <Token> arrDec type expression integerExpr realExpr boolExpr stringExpr functionInvoc
varDec: LET MUT ID ':' type ';' {
Trace("Reducing to varDec Form LET MUT ID ':' type ';'\n");
variableEntry ve = ve_basic_notInit($3.stringVal, $5.tokenType, false);
if (symTabs.isNowGlobal())
{
ve.isGlobal = true;
printTabs();
if (ve.type== T_INT)
fp << "field static int " << ve.name << endl;
else if (ve.type == T_BOOL)
fp << "field static int " << ve.name << endl;
}
else
{
ve.isGlobal = false;
ve.stackIndex = nowStackIndex;
nowStackIndex++;
}
if (!symTabs.addVariable(ve))
yyerror("Re declaration.");
}
| LET MUT ID '=' expression ';' {
Trace("Reducing to varDec Form LET MUT ID '=' expression ';'\n");
variableEntry ve = ve_basic($3.stringVal, $5.tokenType, false);
if ($5.tokenType == T_INT)
ve.data.intVal = $5.intVal;
else if ($5.tokenType == T_FLOAT)
ve.data.floatVal = $5.floatVal;
else if ($5.tokenType == T_BOOL)
ve.data.boolVal = $5.boolVal;
else if ($5.tokenType == T_STRING)
ve.data.stringVal = $5.stringVal;
if (symTabs.isNowGlobal())
{
ve.isGlobal = true;
printTabs();
if (ve.type == T_INT)
fp << "field static int " << ve.name << " = " << ve.data.intVal << endl;
else if (ve.type == T_BOOL)
fp << "field static int " << ve.name << " = " << ve.data.boolVal << endl;
}
else
{
ve.isGlobal = false;
ve.stackIndex = nowStackIndex;
nowStackIndex++;
printTabs();
if (ve.type == T_INT)
fp << "istore " << ve.stackIndex << endl;
else if (ve.type == T_BOOL)
fp << "istore " << ve.stackIndex << endl;
}
if (!symTabs.addVariable(ve))
yyerror("Re declaration.");
}
| LET MUT ID ':' type '=' expression ';' {
Trace("Reducing to varDec Form LET MUT ID ':' type '=' expression ';'\n");
variableEntry ve = ve_basic($3.stringVal, $5.tokenType, false);
if ($5.tokenType == T_FLOAT && $7.tokenType == T_INT)
ve.data.floatVal = $7.intVal;
else if ($5.tokenType != $7.tokenType)
yyerror("expression is not equal to expression");
else if ($7.tokenType == T_INT)
ve.data.intVal = $7.intVal;
else if ($7.tokenType == T_FLOAT)
ve.data.floatVal = $7.floatVal;
else if ($7.tokenType == T_BOOL)
ve.data.boolVal = $7.boolVal;
else if ($7.tokenType == T_STRING)
ve.data.stringVal = $7.stringVal;
if (symTabs.isNowGlobal())
{
ve.isGlobal = true;
printTabs();
if (ve.type == T_INT)
fp << "field static int " << ve.name << " = " << ve.data.intVal << endl;
else if (ve.type == T_BOOL)
fp << "field static int " << ve.name << " = " << ve.data.boolVal << endl;
}
else
{
ve.isGlobal = false;
ve.stackIndex = nowStackIndex;
nowStackIndex++;
printTabs();
if (ve.type == T_INT)
fp << "istore " << ve.stackIndex << endl;
else if (ve.type == T_BOOL)
fp << "istore " << ve.stackIndex << endl;
}
if (!symTabs.addVariable(ve))
yyerror("Re declaration.");
}
| LET MUT ID ';' {
Trace("Reducing to varDec Form LET MUT ID ';'\n");
variableEntry ve = ve_basic_notInit($3.stringVal, T_INT, false);
if (symTabs.isNowGlobal())
{
ve.isGlobal = true;
printTabs();
fp << "field static int " << ve.name << endl;
}
else
{
ve.isGlobal = false;
ve.stackIndex = nowStackIndex;
nowStackIndex++;
}
if (!symTabs.addVariable(ve))
yyerror("Re declaration.");
}
;
I didn't paste them all.
The errors are here.
I don't know how to fix them.
yacc.y:188.33-34: error: symbol ID is used, but is not defined as a token and has no rules
varDec: LET MUT ID ':' type ';' {
^^
yacc.y:191.173-174: error: $3 of ‘varDec’ has no declared type
variableEntry ve = ve_basic_notInit($3.stringVal, $5.tokenType, false);
^^
yacc.y:216.165-166: error: $3 of ‘varDec’ has no declared type
variableEntry ve = ve_basic($3.stringVal, $5.tokenType, false);
^^
yacc.y:256.165-166: error: $3 of ‘varDec’ has no declared type
variableEntry ve = ve_basic($3.stringVal, $5.tokenType, false);
^^
yacc.y:300.173-174: error: $3 of ‘varDec’ has no declared type
variableEntry ve = ve_basic_notInit($3.stringVal, T_INT, false);
Please help me solve problem, thanks.

Related

FLEX/YACC program not behaving as expected : can't grab int value from sequence of ints

I am trying to build a parser that takes a list of strings in the following format and performs either an addition or multiplication of all of its elements :
prod 5-6_
sum _
sum 5_
sum 5-6-7_
$
Should print the following to the screen :
prod = 30
sum = 0
sum = 5
sum = 18
What I am actually getting as output is this :
prod = 0
sum = 0
sum = 5
sum = 5
My lex file looks like this :
%{
#include <iostream>
#include "y.tab.h"
using namespace std;
extern "C" int yylex();
%}
%option yylineno
digit [0-9]
integer {digit}+
operator "sum"|"prod"
%%
{integer} { return number; }
{operator} { return oper; }
"-" { return '-'; }
"_" { return '_'; }
"$" { return '$'; }
\n { ; }
[\t ]+ { ; }
. { cout << "unknown char" << endl; }
%%
and my yacc file looks like this :
%token oper
%token number
%token '-'
%token '_'
%token '$'
%start valid
%{
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define YYSTYPE int
extern FILE *yyin;
extern char yytext[];
extern "C" int yylex();
int yyparse();
extern int yyerror(char *);
char op;
%}
%%
valid : expr_seq endfile {}
| {}
;
expr_seq : expr {}
| expr_seq expr {}
;
expr : op sequence nl {if (op == '+') cout << "sum = " ; else cout << "prod = ";}
| op nl {if (op == '+') cout << "sum = 0"; else cout <<"prod = 1";}
;
op : oper { if (yytext[0] == 's') op = '+'; else op = '*';}
;
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + $3; else $$ = $1 * $3;}
;
nl : '_' { cout << endl;}
;
endfile : '$' {}
;
%%
int main(int argc, char *argv[])
{
++argv, --argc;
if(argc > 0) yyin = fopen(argv[0], "r");
else yyin = stdin;
yyparse();
return 0;
}
int yyerror(char * msg)
{
extern int yylineno;
cerr << msg << "on line # " << yylineno << endl;
return 0;
}
My reasoning for the yacc logic is as follows :
a file is valid only if it contains a sequence of expressions followed by the endfile symbol.
a sequence of expressions is a single expression or several expressions.
an expression is either an operator followed by a new line, OR an operator, followed by a list of numbers, followed by a new line symbol.
an operator is either 'sum' or 'prod'
a list of numbers is either a number or several numbers separated by the '-' symbol.
From my perspective this should work, but for some reason it doesn't interpret the sequence of numbers properly after the first element. Any tips would be helpful.
Thanks
You must not use yytext in your yacc actions. yytext is only valid during a scanner action, and the parser often reads ahead to the next token. (In fact, yacc always reads the next token. Bison sometimes doesn't, but it's not always easily predictable.)
You can associate a semantic value with every token (and non-terminal), and you can reference these semantic values using $1, $2, etc. in your yacc actions. You can even associate semantic values of different types to different grammar symbols. And if you use bison -- and you probably are using bison -- you can give grammar symbols names to make it easier to refer to their semantic values.
This is all explained in depth, with examples, in the bison manual.
The solution that worked was simply to change the following lines :
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + $3; else $$ = $1 * $3;}
;
to this :
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + atoi(yytext); else $$ = $1 * atoi(yytext);}
;

Yacc shift/reduce that I cannot identify

So I am having this .y file on which I am trying to parse and evaluate a function with it's parameters, but a have one shift/reduce conflict that I cannot identify:
.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "types.h"
#define YYDEBUG 0
/* prototypes */
nodeType *opr(int oper, int nops, ...);
nodeType *id(int i);
nodeType *con(int value);
void freeNode(nodeType *p);
void yyerror(char *s);
nodeType *RadEc;
int sym[26]; /* symbol table */
%}
%union {
int iValue; /* integer value */
char sIndex; /* symbol table index */
nodeType *nPtr; /* node pointer */
};
%token <iValue> INTEGER
%token <sIndex> VARIABLE
%token WHILE IF PRINT SUBRAD ENDSUB THEN DO ENDIF RAD
%nonassoc IFX
%nonassoc ELSE
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
%type <nPtr> statement expr stmt_list
%type <iValue> expresie
%start program
%%
program : declaratii cod { exit(0); }
;
declaratii: SUBRAD stmt_list ENDSUB { RadEc=$2; }
| /* NULL */
;
statement : '\n' { $$ = opr(';', 2, NULL, NULL); }
| expr '\n' { $$ = $1; }
| PRINT expr '\n' { $$ = opr(PRINT, 1, $2); }
| VARIABLE '=' expr '\n' { $$ = opr('=', 2, id($1), $3); }
| DO stmt_list WHILE expr { $$ = opr(WHILE, 2, $4, $2); }
| IF expr THEN stmt_list ENDIF %prec IFX { $$ = opr(IF, 2, $2, $4); }
| IF expr THEN stmt_list ELSE stmt_list ENDIF { $$ = opr(IF, 3, $2, $4, $6); }
;
stmt_list : statement
| stmt_list statement { $$ = opr(';', 2, $1, $2); }
;
expr : INTEGER { $$ = con($1); }
| VARIABLE { $$ = id($1); }
| '-' expr %prec UMINUS { $$ = opr(UMINUS, 1, $2); }
| expr '+' expr { $$ = opr('+', 2, $1, $3); }
| expr '-' expr { $$ = opr('-', 2, $1, $3); }
| expr '*' expr { $$ = opr('*', 2, $1, $3); }
| expr '/' expr { $$ = opr('/', 2, $1, $3); }
| expr '<' expr { $$ = opr('<', 2, $1, $3); }
| expr '>' expr { $$ = opr('>', 2, $1, $3); }
| expr GE expr { $$ = opr(GE, 2, $1, $3); }
| expr LE expr { $$ = opr(LE, 2, $1, $3); }
| expr NE expr { $$ = opr(NE, 2, $1, $3); }
| expr EQ expr { $$ = opr(EQ, 2, $1, $3); }
| '(' expr ')' { $$ = $2; }
;
cod : '.' {exit(0);}
| instruc '\n' cod
;
instruc : '\n'
| PRINT expresie {printf("%d\n",$2);}
| VARIABLE '=' expresie {sym[$1]=$3;}
| RAD'('expresie','expresie','expresie')' {sym[0]=$3; sym[1]=$5; sym[2]=$7; ex(RadEc);}
;
expresie : INTEGER { $$ = $1; }
| VARIABLE { $$ = sym[$1]; }
| '-' expresie %prec UMINUS { $$ = -$2; }
| expresie '+' expresie { $$ = $1+$3; }
| expresie '-' expresie { $$ = $1-$3; }
| expresie '*' expresie { $$ = $1*$3; }
| expresie '/' expresie { $$ = $1/$3; }
| expresie '<' expresie { $$ = $1<$3; }
| expresie '>' expresie { $$ = $1>$3; }
| expresie GE expresie { $$ = $1>=$3; }
| expresie LE expresie { $$ = $1<=$3; }
| expresie NE expresie { $$ = $1!=$3; }
| expresie EQ expresie { $$ = $1==$3; }
| '(' expresie ')' { $$ = $2; }
;
%%
nodeType *con(int value)
{
nodeType *p;
/* allocate node */
if ((p = malloc(sizeof(conNodeType))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeCon;
p->con.value = value;
return p;
}
nodeType *id(int i)
{
nodeType *p;
/* allocate node */
if ((p = malloc(sizeof(idNodeType))) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeId;
p->id.i = i;
return p;
}
nodeType *opr(int oper, int nops, ...)
{
va_list ap;
nodeType *p;
size_t size;
int i;
/* allocate node */
size = sizeof(oprNodeType) + (nops - 1) * sizeof(nodeType*);
if ((p = malloc(size)) == NULL)
yyerror("out of memory");
/* copy information */
p->type = typeOpr;
p->opr.oper = oper;
p->opr.nops = nops;
va_start(ap, nops);
for (i = 0; i < nops; i++)
p->opr.op[i] = va_arg(ap, nodeType*);
va_end(ap);
return p;
}
void freeNode(nodeType *p)
{
int i;
if (!p)
return;
if (p->type == typeOpr) {
for (i = 0; i < p->opr.nops; i++)
freeNode(p->opr.op[i]);
}
free (p);
}
int ex(nodeType *p)
{
if (!p)
return 0;
switch(p->type)
{
case typeCon: return p->con.value;
case typeId: return sym[p->id.i];
case typeOpr: switch(p->opr.oper)
{
case WHILE: while(ex(p->opr.op[0]))
ex(p->opr.op[1]);
return 0;
case IF: if (ex(p->opr.op[0]))
ex(p->opr.op[1]);
else if (p->opr.nops > 2)
ex(p->opr.op[2]);
return 0;
case PRINT: printf("%d\n", ex(p->opr.op[0]));
return 0;
case ';': ex(p->opr.op[0]);
return ex(p->opr.op[1]);
case '=': return sym[p->opr.op[0]->id.i] = ex(p->opr.op[1]);
case UMINUS: return -ex(p->opr.op[0]);
case '+': return ex(p->opr.op[0]) + ex(p->opr.op[1]);
case '-': return ex(p->opr.op[0]) - ex(p->opr.op[1]);
case '*': return ex(p->opr.op[0]) * ex(p->opr.op[1]);
case '/': return ex(p->opr.op[0]) / ex(p->opr.op[1]);
case '<': return ex(p->opr.op[0]) < ex(p->opr.op[1]);
case '>': return ex(p->opr.op[0]) > ex(p->opr.op[1]);
case GE: return ex(p->opr.op[0]) >= ex(p->opr.op[1]);
case LE: return ex(p->opr.op[0]) <= ex(p->opr.op[1]);
case NE: return ex(p->opr.op[0]) != ex(p->opr.op[1]);
case EQ: return ex(p->opr.op[0]) == ex(p->opr.op[1]);
}
}
}
void yyerror(char *s)
{
fprintf(stdout, "%s\n", s);
}
int main(void)
{
#if YYDEBUG
yydebug = 1;
#endif
yyparse();
return 0;
}
I tried different ways to see were am I losing something, but I am pretty new at this and still cannot figure it out very well the conflicts.
Any help much appreciated.
Your grammar allows statements to be expressions and it allows two statements to appear in sequence without any separator.
Now, both of the following are expressions:
a
-1
Suppose they appear like that in a statement list. How is that different from this single expression?
a - 1
Ambiguity always shows up as a parsing conflict.
By the way, delimited if statements (with an endif marker) cannot exhibit the dangling else ambiguity. The endif bracket makes the parse unambiguous. So all of the precedence apparatus copied from a different grammar is totally redundant here.

yacc/lex parser not catching certain terminals

I built a scanner->parser meant to catch modified Java. When testing it, I noticed that codeBlock never triggers but varDecls triggers. I'm not entirely sure why this happens.
Here is my parser
%{
#include <stdio.h>
extern int yylex(void);
void yyerror(char *s) {
fprintf(stderr, "error: %s\n", s);
}
int yywrap(){ return 1;}
%}
%token INT FLOAT STRING
%union {
int ival;
float fval;
char *sval;
int bval;
}
%token <ival> NegInt
%token <ival> Int
%token <fval> Float
%token <bval> Bool
%token <sval> ifHeader
%token <sval> thenHeader
%token <sval> elseHeader
%token <sval> forHeader
%token <sval> whileHeader
%token <sval> ID
%token <sval> BinOperator
%token <sval> BoolOperator
%token <sval> Assignment
%token <sval> Quotation
%token <sval> LBracket
%token <sval> RBracket
%token <sval> LFBracket
%token <sval> RFBracket
%token <sval> Semi
%token <sval> LABracket
%token <sval> RABracket
%token <sval> Comma
%token <sval> String
%%
codeBlock: varDecls {printf("why doth this triggering?\n");}
| ifExprs {printf("codeBlock Statement \n");}
;
ifExprs: ifExprs ifStmt
| ifStmt
;
ifStmt: ifExpr | ifExprElse;
ifExprElse: ifExpr elseExpr;
ifExpr: ifHeader LBracket boolExpr RBracket thenExpr;
thenExpr: thenHeader LFBracket varDecls RFBracket;
elseExpr: elseHeader LFBracket varDecls RFBracket;
varDecls: varDecls varDecl
| varDecl
;
varDecl: ID Assignment numStmt Semi
| ID Assignment strExpr Semi
| ID Assignment boolExpr Semi
| ID Assignment Bool Semi {printf("why is this triggering?\n");}
;
boolExpr: ID BoolOperator ID
| ID BoolOperator numExpr
| ID BoolOperator Bool
;
strExpr: Quotation ID Quotation
;
numStmt: numStmt BinOperator numExpr
| numExpr
;
numExpr: LBracket numStmt RBracket
| Int
| Float
| NegInt
;
%%
int main(int argc, char* argv[]) {
yyparse();
}
Here is my scanner:
%{
#include "y.tab.h"
extern YYSTYPE yylval;
%}
%option yylineno
Digit [0-9]
Letter [a-zA-Z]
Word [a-z][a-zA-Z0-9_]*
%%
"-"{Digit}+ {
//printf("\n An assignment: %s \n", yytext);
yylval.ival = atoi(yytext);
return NegInt;
}
{Digit}+ {
//printf("\n An assignment: %s \n", yytext);
yylval.ival = atoi(yytext);
return Int;
}
{Digit}+"."{Digit}+ {
//printf("\n A float: %s (%f)\n", yytext, atof(yytext));
yylval.ival=atof(yytext);
return Float;
}
True|False {
//printf("\n A Boolean: %s \n", yytext);
yylval.bval = atoi(yytext);
return Bool;
}
if {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return ifHeader;
}
then {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return thenHeader;
}
else {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return elseHeader;
}
for {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return forHeader;
}
while {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return whileHeader;
}
{Word} {
//printf("\n An Identifier: %s \n", yytext);
yylval.sval = yytext;
return ID;
}
"'" {
//printf("\n An Identifier: %s \n", yytext);
yylval.sval = yytext;
return Quotation;
}
"+"|"-"|"*"|"/" {
//printf("\n An Operator: %s \n", yytext);
yylval.sval = yytext;
return BinOperator;
}
"<"|">"|"!="|"<="|">="|"==" {
//printf("\n An comparison: %s \n", yytext);
yylval.sval = yytext;
return BoolOperator;
}
"=" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return Assignment;
}
"(" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return LBracket;
}
")" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return RBracket;
}
"{" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return LFBracket;
}
"}" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return RFBracket;
}
";" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return Semi;
}
"[" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return LABracket;
}
"]" {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return RABracket;
}
"," {
//printf("\n An assignment: %s \n", yytext);
yylval.sval = yytext;
return Comma;
}
%
As you can see with my print statements, I was trying to trigger my parser to print out "why doth this triggering" but instead varDecls is triggered instead.
Additionally, varDecl also triggers. Is that supposed to happen?
Help would be very appreciated. Thank you

bisonc++ - No production rules?

I'm trying to compile the following with bisonc++:
%baseclass-preinclude <iostream>
%lsp-needed
%token NUMBER COMMENT KEYWORD VARIABLE LOGICAND LOGICOR LOGICEQUALS DOUBLELESSER
%token DOUBLEGREATER MOD LESSER GREATER OPEN CLOSE NEGATE CURLYOPEN CURLYCLOSE SEMICOLON
%left EQUALS
%left PLUS MINUS
%left TIMES
%left DIVISION
%%
start:
expressions
{
std::cout << "start -> expressions" << std::endl;
}
;
expressions:
// empty
{
std::cout << "expressions -> epsylon" << std::endl;
}
|
exp expressions
{
std::cout << "expressions -> exp expressions" << std::endl;
}
;
exp:
NUMBER
{
std::cout << "exp -> NUMBER" << std::endl;
}
|
COMMENT
{
std::cout << "exp -> COMMENT" << std::endl;
}
|
exp LOGICAND exp
{
std::cout << "exp -> exp LOGICAND exp" << std::endl;
}
|
exp LOGICOR exp
{
std::cout << "exp -> exp LOGICOR exp" << std::endl;
}
|
exp LOGICEQUALS exp
{
std::cout << "exp -> exp LOGICEQUALS exp" << std::endl;
}
|
exp DOUBLELESSER exp
{
std::cout << "exp -> exp DOUBLELESSER exp" << std::endl;
}
|
exp DOUBLEGREATER exp
{
std::cout << "exp -> exp DOUBLEGREATER exp" << std::endl;
}
|
exp PLUS exp
{
std::cout << "exp -> exp PLUS exp" << std::endl;
}
|
exp MINUS exp
{
std::cout << "exp -> exp MINUS exp" << std::endl;
}
|
exp TIMES exp
{
std::cout << "exp -> exp EQUAL exp" << std::endl;
}
|
exp EQUAL exp
{
std::cout << "exp -> exp EQUAL exp" << std::endl;
}
|
exp DIVISION exp
{
std::cout << "exp -> exp DIVISION exp" << std::endl;
}
|
exp MOD exp
{
std::cout << "exp -> exp MOD exp" << std::endl;
}
|
exp LESSER exp
{
std::cout << "exp -> exp LESSER exp" << std::endl;
}
|
exp GREATER exp
{
std::cout << "exp -> exp GREATER exp" << std::endl;
}
|
OPEN exp CLOSE
{
std::cout << "exp -> OPEN exp CLOSE" << std::endl;
}
|
NEGATE exp
{
std::cout << "exp -> NEGATE exp" << std::endl;
}
|
CURLYOPEN exp CURLYCLOSE
{
std::cout << "exp -> CURLYOPEN exp CURLYCLOSE" << std::endl;
}
|
exp SEMICOLON
{
std::cout << "exp -> SEMICOLON" << std::endl;
}
|
KEYWORD VARIABLE SEMICOLON
{
std::cout << "exp -> KEYWORD VARIABLE SEMICOLON" << std::endl;
}
;
However, it keeps returning with the error
') encountered.1] Line 1: unrecognized input (`
': identifier or character-constant expected.
[bead.y: fatal] Line 23: No production rules
134950080
I obviously have some production rules and have no idea what I'm doing wrong. I've copied most of the code from another working example and modified it to my liking. What is wrong?
Your files are not UNIX conform (calculate.l and calculate.y)
If you're operating on Windows and you use Nodepad++, just do the following:
Edit/EOL conversion/UNIX format
Encoding/Convert your files to UTF-8 without BOM
Save and recompile with flex and bisonc++
Hope this helps
I had the same problem, and my teacher showed me, that some of the windows editors create invisible trash in your file, so edit your file with the terminal.
pico yourfile.y
Hit an Enter before the first line, than erase it.
Save
Thats it!

Syntax error while parsing file using flex and bison

I am parsing the following file:
BEGIN BLOCK BLK_ROWDEC
NAME cell_rowdec
SIZE UNI_rowdecSize
ITERATE itr_rows
DIRECTION lgDir_rowdec
STRAP STRD1,STRD3,STRD2
WRAP WRD1
VIA VIAB,VIAC,VIAD
ENDS BLK_ROWDEC
My flex and bison file are as follows:
lexa.l
%{
#include <iostream>
#include <stdio.h>
const char s[2] = " ";
#include "yacc.tab.h"
char *token;
#define YY_DECL extern "C" int yylex()
int line_num = 1;
using namespace std;
%}
DOT "."
COLON ":"
SEMICOLON ";"
COMMA ","
ANGLE_LEFT "<"
ANGLE_RIGHT ">"
AT "#"
EQUAL "="
SQUARE_OPEN "["
SQUARE_CLOSE [^\\]"]"
OPENBRACE "\("
CLOSEBRACE "\)"
QUOTE "\""
QUOTE_OPEN "\""
QUOTE_CLOSE [^\\]"\""
SPACE " "
TAB "\t"
CRLF "\r\n"
QUOTED_PAIR "\\"[^\r\n]
DIGIT [0-9]
ALPHA [a-zA-Z]
QTEXT [0-9a-zA-Z!#$%&'()*+,\-.\/:;<=>?#\[\]^_`{|}~]
%%
[ \t] ;
^BEGIN(.*)\r?\n+\s*BEGIN(.*) { printf("\nError : two continous BEGIN is not allowed : "); }
^ENDS(.*)\r?\n+\s*ENDS(.*) { printf("\nError : two continous END is not allowed : \n"); }
NAME { yylval.sval = strdup(yytext);
return TOK_NAME; }
SIZE { yylval.sval = strdup(yytext);
return TOK_SIZE; }
ITERATE { yylval.sval = strdup(yytext);
return TOK_ITERATE; }
DIRECTION { yylval.sval = strdup(yytext);
return TOK_DIRECTION; }
STRAP { yylval.sval = strdup(yytext);
return TOK_STRAP; }
WRAP { yylval.sval = strdup(yytext);
return TOK_WRAP; }
VIA { yylval.sval = strdup(yytext);
return TOK_VIA; }
ENDS { yylval.sval = strdup(yytext);
return TOK_END; }
BEGIN { yylval.sval = strdup(yytext);
return TOK_BEGIN; }
BLOCK { yylval.sval = strdup(yytext);
return TOK_BLOCK; }
[a-zA-Z0-9_,]+ { yylval.sval = strdup(yytext);
return TOK_STRING; }
{SPACE}* { return TOK_SPACE; }
^ENDS(.*)$ {}
^{CRLF} { return TOK_EMPTY_LINE; }
{CRLF} {}
. {}/* ignore unknown chars */
\n { ++line_num; return ENDL; }
yacca.y
%{
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdio.h>
#define YYDEBUG 1
using namespace std;
extern "C" int yylex();
extern "C" FILE *yyin;
extern int line_num;
void yyerror(const char* s);
%}
// Symbols.
%union
{
char* sval;
};
%token <sval> TOK_NAME
%token <sval> TOK_SIZE
%token <sval> TOK_STRING
%token <sval> TOK_ITERATE
%token <sval> TOK_DIRECTION
%token <sval> TOK_STRAP
%token <sval> TOK_WRAP
%token <sval> TOK_VIA
%token <sval> TOK_EMPTY_LINE
%token <sval> TOK_BLOCK
%token <sval> TOK_LINE
%token <sval> TOK_BEGIN
%token <sval> TOK_END
%token TOK_SPACE
%token END ENDL
%%
language : program ;
program : block
| program block
;
block : TOK_BEGIN TOK_BLOCK TOK_SPACE TOK_STRING blockcontents TOK_END TOK_SPACE TOK_STRING
{
cout << endl << "SHAILAVI" << $4 << " ";
}
;
blockcontents : item
| blockcontents item
;
item : TOK_SPACE TOK_NAME TOK_SPACE TOK_STRING
{
cout << endl << "Value:" << $2 << "->" << $4 << " ";
}
| TOK_SPACE TOK_SIZE TOK_SPACE TOK_STRING { cout << $2 << "->" << $4 << " "; }
| TOK_SPACE TOK_ITERATE TOK_SPACE TOK_STRING { cout << $2 << "->" << $4 << " "; }
| TOK_SPACE TOK_DIRECTION TOK_SPACE TOK_STRING { cout << $2 << "->" << $4 << " " << endl; }
| TOK_SPACE TOK_STRAP TOK_SPACE TOK_STRING { cout << "ref:" << $2 << "->" << $4 << " "; }
| TOK_SPACE TOK_WRAP TOK_SPACE TOK_STRING { cout << $2 << "->" << $4 << " "; }
| TOK_SPACE TOK_VIA TOK_SPACE TOK_STRING { cout << $2 << "->" << $4 << " " << endl; }
;
%%
int main(void) {
FILE * pt = fopen("file", "r" );
if(!pt)
{
cout << "Bad Input.Noexistant file" << endl;
return -1;
}
yyin = pt;
do
{
yydebug = 1;
yyparse();
}while (!feof(yyin));
}
void yyerror(const char *s) {
cout << "parse error on line " << line_num << "! Message: " << s << endl;
exit(-1);
}
#include "lex.yy.c"
Compilation steps:
flex lexa.l
bison -d yacca.y
g++ yacca.tab.c -lfl -o scanner.exe
At the time of execution it gives syntax error near blockcontents
Please help me to identify the mistake I have done.
Thank You so much.
It took me a while, but I've found the flaw.
In your lexer, you skip all sequences of tabs and blanks (first rule).
But your parser expects white space every now and then. Hence the syntax error.
Since you don't do anything with the white space, simply eat them within the lexer (as you already do now actually, but it is better to eliminate the {SPACE}* rule too) and eliminate the TOK_SPACE in the parser.
---- edit to give some hints ----
What I did to track down the bug is:
make the lexer verbose
I added (hash signs omitted; it confuses the renderer for some reason)
#ifdef DEBUG
#define RETURN(x) cerr << "\n--> found " << #x << "\n"; return x;
#else
#define RETURN(x) return x;
#endif
and replaced all "return something" by RETURN(something)
I compile the bison/flex files separately and link them afterwards
flex lexa.l && \
bison -d yacca.y && \
g++ -c -DDEBUG -I . lex.yy.c && \
g++ -c -I . yacca.tab.c && \
g++ lex.yy.o yacca.tab.o -o scanner
(working on linux here)
As requested the working example
%{
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdio.h>
#define YYDEBUG 1
using namespace std;
extern "C" int yylex();
extern "C" FILE *yyin;
extern int line_num;
void yyerror(const char* s);
%}
// Symbols.
%union
{
char* sval;
};
%token TOK_NAME
%token TOK_SIZE
%token TOK_STRING
%token TOK_ITERATE
%token TOK_DIRECTION
%token TOK_STRAP
%token TOK_WRAP
%token TOK_VIA
%token TOK_EMPTY_LINE
%token TOK_BLOCK
%token TOK_LINE
%token TOK_BEGIN
%token TOK_END
%token END ENDL
%%
language : program ;
program : block
| program block
;
block : TOK_BEGIN TOK_BLOCK TOK_STRING blockcontents TOK_END TOK_STRING
{
cout << endl << "SHAILAVI" << $3 << " ";
}
;
blockcontents : item
| blockcontents item
;
item : TOK_NAME TOK_STRING { cout << endl << "Value:" << $1 << "->" << $2 << " "; }
| TOK_SIZE TOK_STRING { cout << $1 << "->" << $2 " << $2 " << $2 " << $2 << " "; }
| TOK_WRAP TOK_STRING { cout << $1 << "->" << $2 << " "; }
| TOK_VIA TOK_STRING { cout << $1 << "->" << $2 << " " << endl; }
;
%%
int main(void) {
FILE * pt = fopen("./input", "r" );
if(!pt)
{
cout << "Bad Input.Nonexistent file" << endl;
return -1;
}
yyin = pt;
do
{
yydebug = 1;
yyparse();
}while (!feof(yyin));
}
void yyerror(const char *s) {
cout << "parse error on line " << line_num << "! Message: " << s << endl;
exit(-1);
}
extern "C" int yywrap()
{
return (1 == 1);
}
And the lexer
%{
#include
#include
const char s[2] = " ";
#include "yacca.tab.h"
char *token;
#define YY_DECL extern "C" int yylex()
int line_num = 1;
#ifdef DEBUG
#define RETURN(x) cerr << "\n--> found " << #x << "\n"; return x;
#else
#define RETURN(x) return x;
#endif
using namespace std;
%}
DOT "."
COLON ":"
SEMICOLON ";"
COMMA ","
ANGLE_LEFT ""
AT "#"
EQUAL "="
SQUARE_OPEN "["
SQUARE_CLOSE [^\\]"]"
OPENBRACE "\("
CLOSEBRACE "\)"
QUOTE "\""
QUOTE_OPEN "\""
QUOTE_CLOSE [^\\]"\""
SPACE " "
TAB "\t"
CRLF "\r\n"
QUOTED_PAIR "\\"[^\r\n]
DIGIT [0-9]
ALPHA [a-zA-Z]
QTEXT [0-9a-zA-Z!#$%&'()*+,\-.\/:;?#\[\]^_`{|}~]
/* [ \t] ; */
%%
^BEGIN(.*)\r?\n+\s*BEGIN(.*) { printf("\nError : two continous BEGIN is not allowed : "); }
^ENDS(.*)\r?\n+\s*ENDS(.*) { printf("\nError : two continous END is not allowed : \n"); }
NAME { yylval.sval = strdup(yytext);
RETURN(TOK_NAME); }
SIZE { yylval.sval = strdup(yytext);
RETURN(TOK_SIZE); }
ITERATE { yylval.sval = strdup(yytext);
RETURN(TOK_ITERATE); }
DIRECTION { yylval.sval = strdup(yytext);
RETURN(TOK_DIRECTION); }
STRAP { yylval.sval = strdup(yytext);
RETURN(TOK_STRAP); }
WRAP { yylval.sval = strdup(yytext);
RETURN(TOK_WRAP); }
VIA { yylval.sval = strdup(yytext);
RETURN(TOK_VIA); }
ENDS { yylval.sval = strdup(yytext);
RETURN(TOK_END); }
BEGIN { yylval.sval = strdup(yytext);
RETURN(TOK_BEGIN); }
BLOCK { yylval.sval = strdup(yytext);
RETURN(TOK_BLOCK); }
[a-zA-Z0-9_,]+ { yylval.sval = strdup(yytext); RETURN(TOK_STRING); }
^ENDS(.*)$ {}
^{CRLF} { RETURN(TOK_EMPTY_LINE); }
{CRLF} {}
. {}/* ignore unknown chars */
\n { ++line_num; /* RETURN(ENDL); */ }
There's only one problem left. It doesn't really like the EOF. I'll leave that as an exercise.

Resources