-
Notifications
You must be signed in to change notification settings - Fork 88
/
flexexample5.y
56 lines (47 loc) · 1.61 KB
/
flexexample5.y
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
/* Parser to convert "C" assignments to lisp using Bison in C. */
/* Demonstrates bison pure parser with parameters passed to yyparse and to yylex */
/* Compile: bison -d -y flexexample5.y */
%{
#include "lex.yy.h" /* Generated by reflex: scanner_t, yyscan_t, yylex_init, yylex_destroy */
/* %pure-parser requires us to pass the argument 'params->scanner' from yyparse through to yylex. */
#define YYLEX_PARAM params->scanner
/* Pass argument `struct pass_through *param` with scanner object and other data */
struct pass_through {
yyscanner_t *scanner;
int count;
};
void yyerror(struct pass_through *param, const char *msg); /* yyerror accepts `params` */
%}
/* pure-parser adds yylval parameter to yylex() */
%pure-parser
/* Add params->scanner parameter to yylex() with a trick: use YYLEX_PARAM */
%lex-param { void *YYLEX_PARAM }
/* Add pass-through parameter to yyparse() */
%parse-param { struct pass_through *params }
%union {
int num;
char *str;
}
%token <str> STRING
%token <num> NUMBER
%%
assignments : assignment
| assignment assignments
;
assignment : STRING '=' NUMBER ';' { printf("(setf %s %d)\n", $1, $3); ++params->count; }
;
%%
int main()
{
struct pass_through params;
yyscanner_t scanner; // new way in C++ using reflex-generated yyscanner_t
params.scanner = &scanner;
params.count = 0;
yyparse(¶ms); // %parse-param, we pass params->scanner on to yylex()
printf("# assignments = %d\n", params.count);
return 0;
}
void yyerror(struct pass_through *params, const char*)
{
fprintf(stderr, "syntax error at %zu\n", params->scanner->matcher().lineno());
}