Problem with my parser.y (FLEX/BISON)

I am learning Flex/Bison and we are currently on the part about semantics, previously have dealt with lexical and syntax errors. I have googled extensively and haven't been able to find a solution to my error.


When I try to makefile I get this error:

flex scanner.l
mv lex.yy.c scanner.c
bison -d -v parser.y
paser.y:114.71-72: error: $4 of 'case' has no declared type
114 | case WHEN INT_LITERAL ARROW statement_ {case_statements.push_back($4);};

Here is the pseudo code I am trying to follow:

statement:

CASE expression IS cases OTHERS ARROW statement_ ENDCASE

{If the attribute of cases, is a number then

return it as the attribute otherwise return the

attribute of the OTHERS clause};

cases:

cases case

{if the attribute of cases is a number then return it as the
attribute otherwise return the attribute of case} |

%empty

{Set the attribute to the sentinel NAN} ;

case:

WHEN INT_LITERAL ARROW statement_

{$-2 contains the value of the expression after CASE.

It must be compared with the attribute of INT_LITERAL.

If they match the attribute of this production

should become the attribute of statement_

If they don't match, the attribute should be set to the

sentinel value NAN} ;

Here is the parser.y file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
%{

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <math.h>

using namespace std;

#include "values.h"
#include "listing.h"
#include "symbols.h"
#include <stdlib.h>
#include <stdio.h>

int yylex();
void yyerror(const char* message);

Symbols<int> symbols;

//----------------------------------------------------------------------------------------------

vector<int> case_statements;  //<<<<<<<<<<<<Is this wrong?

//---------------------------------------------------------------------------------------------

int result;
double *params;

%}

%define parse.error verbose

%union
{
	CharPtr iden;
	Operators oper;
	int value;
}

%token <iden> IDENTIFIER
%token <value> INT_LITERAL REAL_LITERAL BOOL_LITERAL CASE TRUE FALSE

%token <oper> ADDOP MULOP RELOP OROP NOTOP REMOP EXPOP
%token ANDOP

%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%token THEN WHEN ARROW
%token ELSE ENDCASE ENDIF IF OTHERS REAL

%type <value> body statement_ statement reductions expression relation term
	factor case cases exponent unary primary
%type <oper> operator

%%

function:	
	function_header optional_variable body {result = $3;} ;
	
function_header:	
	FUNCTION IDENTIFIER optional_parameter RETURNS type ';' |
    FUNCTION IDENTIFIER RETURNS type ';' |
    error ';' ;

optional_variable:
	optional_variable variable | 
    error ';' | 
    %empty ;

variable:	
	IDENTIFIER ':' type IS statement_ ;

parameters:
    parameter optional_parameter;

optional_parameter:
    optional_parameter ',' parameter |
    %empty ;

parameter:
    IDENTIFIER ':' type {symbols.insert($1, params[0]);} ;

type:
	INTEGER |
    REAL |
	BOOLEAN ;

body:
	BEGIN_ statement_ END ';' {$$ = $2;} ;
    
statement_:
	statement ';' |
	error ';' {$$ = 0;} ;
	
statement:
	expression |
	REDUCE operator reductions ENDREDUCE {$$ = $3;} |
    IF expression THEN statement_ ELSE statement_ ENDIF {
        if ($2 == true) {
            $$ = $4;
        }
        else {
            $$ = $6;
        }
    } ; |
    CASE expression IS cases OTHERS ARROW statement_ ENDCASE {$$ = $<value>4 == $1 ? $4 : $7;} ;

cases:
    cases case {$$ = $<value>1 == $1 ? $1 : $2;} |
    %empty {$$ = NAN;} ;

//-----------------------------------------------------------------------------------------------------------

case:
    case WHEN INT_LITERAL ARROW statement_ {case_statements.push_back($4);} ;  //<<<<<<<<<How do I declare $4?

//-------------------------------------------------------------------------------------------------------------

operator:
	ADDOP |
    RELOP |
    EXPOP |
	MULOP ;

reductions:
	reductions statement_ {$$ = evaluateReduction($<oper>0, $1, $2);} |
	{$$ = $<oper>0 == ADD ? 0 : 1;} %empty ;

expression:
    expression OROP relation {$$ = $1 || $3;} |
    relation ;

expression:
	expression ANDOP relation {$$ = $1 && $3;} |
	relation ;

relation:
	relation RELOP term {$$ = evaluateRelational($1, $2, $3);} |
	term ;

term:
	term ADDOP factor {$$ = evaluateArithmetic($1, $2, $3);} |
	factor ;
      
factor:
	factor MULOP primary {$$ = evaluateArithmetic($1, $2, $3);} |
    factor REMOP exponent {$$ = $1 % $3;} |
	exponent ;

exponent:
    unary |
    unary EXPOP exponent {$$ = pow($1, $3);} ;

unary:
    NOTOP primary {$$ = $2;} |
    primary;

primary:
	'(' expression ')' {$$ = $2;} |
	INT_LITERAL |
    REAL_LITERAL |
    BOOL_LITERAL |
	IDENTIFIER {if (!symbols.find($1, $$)) appendError(UNDECLARED, $1);} ;

%%

void yyerror(const char* message)
{
	appendError(SYNTAX, message);
}

int main(int argc, char *argv[])    
{
    params = new double[argc - 1]
    for (int i = 1; i < argc; i++)
    {
        params[i - 1] = atof(argv[i]);
    }
	firstLine();
	yyparse();
	if (lastLine() == 0)
		cout << "Result = " << result << endl;
	return 0;
} 
Last edited on
Because the code tags on this forum are [code][/code], not <code></code>
https://www.cplusplus.com/articles/jEywvCM9/

You can edit your post to fix this.
Last edited on
Thank you for the help editing my post's format salem
Last edited on
Topic archived. No new replies allowed.