Bonjour à tous et à toutes,

J'essaye de me mettre au C avec Flex et Bison. (ce qui n'est pas une mince affaire pour moi...)
Je rencontre un problème, que je pense être une erreur de noob.
Mais je n'arrive pas à la corriger.

Auriez-vous l'aimabilité de bien vouloir m'aider, svp ? Je souffre depuis presque deux jours.
Merci de votre aide.

L'erreur:
utils.c: In function 'ExecuteLine':
utils.c:34:16: error: implicit declaration of function 'parse_string' [-Wimplicit-function-declaration]
34 | return parse_string(line);
Le fichier C concerné:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#include "utils.h"
 
// get the red tint from a palette color
Uint8 GetPaletteRed(unsigned char palette_color) {
	return CPC_palette[palette_color].r;
};
 
// get the green tint from a palette color
Uint8 GetPaletteGreen(unsigned char palette_color) {
	return CPC_palette[palette_color].g;
};
 
// get the blue tint from a palette color
Uint8 GetPaletteBlue(unsigned char palette_color) {
	return CPC_palette[palette_color].b;
};
 
// read a line of code in the full source code
void ReadSourceCodeLine(unsigned int line) {
	for(unsigned int i = 0; i <= CPC_SCREEN_MATRIX_WIDTH + 1; i++) {
		CPC_current_line[line] = 0;
	}
 
	if(line >= 1 && line < CPC_MAX_LINES_OF_CODE) {
		for(unsigned int i = 0; i < CPC_SCREEN_MATRIX_WIDTH; i++) {
			CPC_current_line[i] = CPC_source_code[i][line].letter;
		}
	}
}
 
// execute a line of code
int ExecuteLine(char *line) {
	return parse_string(line);
}
Le fichier Flex:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
/* lexer for CPC++ */
 
%{
#ifndef _LEXER_L_
#define _LEXER_L_
 
#include "parser.tab.h"
 
#endif
%}
 
%option yylineno
%option noinput
%option nounput
%option noyywrap
%option caseless
 
%%
 
"ABS"						{ return FN_ABS; }
"INT"						{ return FN_INT; }
"SGN"						{ return FN_SGN; }
 
"CLG"						{ return KW_CLG; }
"CLS"						{ return KW_CLS; }
"DRAWR"						{ return KW_DRAWR; }
"DRAW"						{ return KW_DRAW; }
"FILL"						{ return KW_FILL; }
"GPAPER"					{ return KW_GPAPER; }
"GPEN"						{ return KW_GPEN; }
"INK"						{ return KW_INK; }
"LOCATE"					{ return KW_LOCATE; }
"MODE"						{ return KW_MODE; }
"MOVER"						{ return KW_MOVER; }
"MOVE"						{ return KW_MOVE; }
"ORIGIN"					{ return KW_ORIGIN; }
"PAPER"						{ return KW_PAPER; }
"PEN"						{ return KW_PEN; }
"PLOTR"						{ return KW_PLOTR; }
"PLOT"						{ return KW_PLOT; }
"PRINT"						{ return KW_PRINT; }
 
"("							{ return OP; }
")"							{ return CP; }
","							{ return COMMA; }
":"							{ return COLON; }
";"							{ return SEMICOLON; }
[0-9]+\.[0-9]+ 				{ yylval.dval = atof(yytext); return NUMFLOAT; }
[0-9]+						{ yylval.ival = atoi(yytext); return NUMINT; }
\"[^"]*\"					{ yylval.sval = yytext; return ALPHANUM; }
"+"							{ return PLUS; }
"-"							{ return MINUS; }
"*"							{ return MUL; }
"/"							{ return DIV; }
"\\"						{ return EDIV; }
"MOD"						{ return MOD; }
[ \t]						{ /* ignore spaces */ }
\n							{ return EOL; }
.							{ return GARBAGE; }
 
%%
 
void set_input_string(const char* s) {
  yy_scan_string(s);
}
 
void end_lexical_scan(void) {
  yy_delete_buffer(YY_CURRENT_BUFFER);
}
Le fichier Bison:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
186
187
188
189
190
191
192
193
 
/* parser for CPC++ */
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
 
#include "functions.h"
 
char st[1024];
 
int yylex(void);
int yyerror(const char* s);
 
extern int yylineno;
 
void set_input_string(const char* s);
void end_lexical_scan(void);
 
%}
 
%union {
	int ival;
	double dval;
	char *sval;
}
 
 
// function tokens
%token FN_ABS
%token FN_INT
%token FN_SGN
 
// keywords tokens
%token KW_CLG
%token KW_CLS
%token KW_DRAWR
%token KW_DRAW
%token KW_FILL
%token KW_GPAPER // also used as function
%token KW_GPEN // also used as function
%token KW_INK
%token KW_LOCATE
%token KW_MODE // also used as function
%token KW_MOVER
%token KW_MOVE
%token KW_ORIGIN
%token KW_PAPER // also used as function
%token KW_PEN // also used as function
%token KW_PLOTR
%token KW_PLOT
%token KW_PRINT
 
// additionnals tokens
%token OP
%token CP
%token COMMA
%token COLON
%token SEMICOLON
%token <dval> NUMFLOAT
%token <ival> NUMINT
%token <sval> ALPHANUM
%token PLUS
%token MINUS
%token MUL
%token DIV
%token EDIV
%token MOD
%token EOL
%token GARBAGE
 
%type <dval> func param exp factor term
%type <ival> iparam
%type <sval> sparamlist sparam numstringparam strings2 strings1 string
 
%%
 
execute: /* nothing here */
 | execute line EOL
 | execute EOL
;
 
line: colons
 | command
 | command colons
 | line command
 | line command colons
;
 
colons: COLON
 | colons COLON
;
 
command: KW_CLG { CPC_CLG(); }
 | KW_CLS { CPC_CLS(); }
 | KW_DRAWR iparam COMMA iparam COMMA iparam { CPC_DRAWR3($2, $4, $6); }
 | KW_DRAWR iparam COMMA iparam { CPC_DRAWR2($2, $4); }
 | KW_DRAW iparam COMMA iparam COMMA iparam { CPC_DRAW3($2, $4, $6); }
 | KW_DRAW iparam COMMA iparam { CPC_DRAW2($2, $4); }
 | KW_FILL iparam COMMA iparam COMMA iparam { CPC_FILL3($2, $4, $6); }
 | KW_FILL iparam COMMA iparam { CPC_FILL2($2, $4); }
 | KW_GPAPER iparam { CPC_GRAPHIC_PAPER($2); }
 | KW_GPEN iparam { CPC_GRAPHIC_PEN($2); }
 | KW_MOVER iparam COMMA iparam { CPC_MOVER($2, $4); }
 | KW_MOVE iparam COMMA iparam { CPC_MOVE($2, $4); }
 | KW_ORIGIN iparam COMMA iparam { CPC_ORIGIN($2, $4); }
 | KW_INK iparam COMMA iparam { CPC_INK($2, $4); }
 | KW_LOCATE iparam COMMA iparam { CPC_LOCATE($2, $4); }
 | KW_MODE iparam { CPC_MODE($2); }
 | KW_PAPER iparam { CPC_PAPER($2); }
 | KW_PEN iparam { CPC_PEN($2); }
 | KW_PLOTR iparam COMMA iparam COMMA iparam { CPC_PLOTR3($2, $4, $6); }
 | KW_PLOTR iparam COMMA iparam { CPC_PLOTR2($2, $4); }
 | KW_PLOT iparam COMMA iparam COMMA iparam { CPC_PLOT3($2, $4, $6); }
 | KW_PLOT iparam COMMA iparam { CPC_PLOT2($2, $4); }
 | KW_PRINT sparamlist { CPC_PRINT((char*)$2); }
;
 
sparamlist: sparam { $$ = $1; }
 | sparamlist COMMA sparam { $$ = strcat($1, $3); }
;
 
sparam: strings1
 | strings2
 | numstringparam
;
 
numstringparam: param { if(round($1) != $1) { sprintf(st, "%f", $1); } else { sprintf(st, "%d", (int)$1); } $$ = (char*)st; }
;
 
func: FN_ABS OP param CP { $$ = fabs($3); }
 | KW_MODE OP CP { $$ = (double)CPC_GET_MODE(); }
 | KW_GPAPER OP CP { $$ = (double)CPC_GET_GRAPHIC_PAPER(); }
 | KW_GPEN OP CP { $$ = (double)CPC_GET_GRAPHIC_PEN(); }
 | FN_INT OP param CP { $$ = (double)CPC_INT($3); }
 | KW_PAPER OP CP { $$ = (double)CPC_GET_PAPER(); }
 | KW_PEN OP CP { $$ = (double)CPC_GET_PEN(); }
 | FN_SGN OP param CP { $$ = (double)CPC_SGN($3); }
;
 
iparam: param { $$ = (int)round($1); }
;
 
param: exp
 | PLUS exp { $$ = $2; }
 | MINUS exp { $$ = -$2; }
;
 
exp: factor
 | exp PLUS factor { $$ = $1 + $3; }
 | exp MINUS factor { $$ = $1 - $3; }
;
 
factor: term
 | factor MUL term { $$ = $1 * $3; }
 | factor DIV term { $$ = $1 / $3; }
 | factor EDIV term { $$ = (double)((int)((int)$1 / (int)$3)); }
 | factor MOD term { $$ = (double)(((int)$1) % ((int)$3)); }
;
 
term: NUMINT { $$ = (double)$1; }
 | NUMFLOAT
 | func;
;
 
strings2: string SEMICOLON { $$ = $1;}
 | strings2 string { $$ = strcat($1, $2);}
 | strings2 string SEMICOLON { $$ = strcat($1, $2);}
;
 
strings1: string { $$ = $1;}
 | strings1 PLUS string { $$ = strcat($1, $3);}
;
 
string: ALPHANUM { char* p = $$; p++; p[strlen(p) - 1] = 0; $$ = p; }
;
 
%%
 
int yyerror(const char *s) {
	// show syntax error at line
	//ed->SetError(ERR_SYNTAX_ERROR, "Syntax error", yylineno);
	return 1;
}
 
// parses a string
int parse_string(const char* s) {
	set_input_string(s);
	int ret = yyparse();
	end_lexical_scan();
	return ret;
}