1 /* $NetBSD: btyacc_demo.y,v 1.1.1.1 2015/01/03 22:58:23 christos Exp $ */
4 * demonstrate enhancements derived from btyacc:
5 * backtracking to resolve conflicts
6 * semantic disambiguation via []-actions invoking YYVALID & YYERROR
8 * @$ & @N to refer to lhs & rhs symbol location
10 * syntactic suger for inherited attributes
11 * extension to %type to define inherited attribute type
17 /* dummy types just for compile check */
19 typedef
int Decl_List
;
21 typedef
int Expr_List
;
24 enum Operator
{ ADD
, SUB
, MUL
, MOD
, DIV
, DEREF
};
26 typedef
unsigned char bool;
33 #include "btyacc_demo.tab.h"
52 %nonassoc POSTFIX
'(' '[' '.'
55 %token
<expr
> CONSTANT
56 %token EXTERN REGISTER STATIC CONST VOLATILE IF THEN ELSE CLCL
58 %type
<expr
> expr
(<scope
>)
59 %type decl
(<scope
>) declarator_list
(<scope
>, <type
>)
61 %type
<code
> statement
(<scope
>) statement_list
(<scope
>)
62 block_statement
(<scope
>)
63 %type
<decl
> declarator
(<scope
>, <type
>) formal_arg
(<scope
>)
64 %type
<type
> decl_specs
(<scope
>) decl_spec
(<scope
>) typename
(<scope
>)
66 %type
<scope
> opt_scope
(<scope
>)
67 %type
<dlist
> formal_arg_list
(<scope
>) nonempty_formal_arg_list
(<scope
>)
69 %destructor
{ // 'msg' is a 'char *' indicating the context of destructor invocation
70 printf
("%s accessed by symbol \"decl\" (case s.b. 273) @ position[%d,%d..%d,%d]\n",
72 @$.first_line
, @$.first_column
,
73 @$.last_line
, @$.last_column
);
74 free
($
<decl
>$
->scope
); free
($
<decl
>$
->type
); } decl
75 %destructor
{ printf
("%s accessed by symbol with type <decl> (case s.b. 279 & 280) @ position[%d,%d..%d,%d]\n",
77 @$.first_line
, @$.first_column
,
78 @$.last_line
, @$.last_column
);
80 %destructor
{ printf
("%s accessed by symbol of any type other than <decl> @ position[%d,%d..%d,%d]\n",
82 @$.first_line
, @$.first_column
,
83 @$.last_line
, @$.last_column
);
85 %destructor
{ printf
("%s accessed by symbol with no type @ position[%d,%d..%d,%d]\n",
87 @$.first_line
, @$.first_column
,
88 @$.last_line
, @$.last_column
);
89 /* in this example, we don't know what to do here */ } <>
95 opt_scope
($e): [ $$
= $e; ]
96 | CLCL
[ $$
= global_scope
; ]
97 | opt_scope ID CLCL
[ Decl
*d
= lookup
($1, $2);
98 if
(!d ||
!d
->scope
) YYERROR;
102 typename
($e): opt_scope ID
103 [ Decl
*d
= lookup
($1, $2);
104 if
(d
== NULL || d
->istype
() == 0) YYERROR;
108 input: decl_list
(global_scope
= new_scope
(0)) ;
109 decl_list
($e): | decl_list decl
($e) ;
111 decl_specs declarator_list
($e,$1) ';' [YYVALID
;]
112 | decl_specs declarator
($e,$1) block_statement
(start_fn_def
($e, $2))
113 { /* demonstrate use of @$ & @N, although this is just the
114 default computation and so is not necessary */
115 @$.first_line
= @
1.first_line
;
116 @$.first_column
= @
1.first_column
;
117 @$.last_line
= @
3.last_line
;
118 @$.last_column
= @
3.last_column
;
119 finish_fn_def
($2, $3); }
123 decl_spec
[ $$
= $1; ]
124 | decl_specs decl_spec
($e) [ $$
= type_combine
($1, $2); ]
127 cv_quals: [ $$
= 0; ]
128 | cv_quals cv_qual
[ $$
= type_combine
($1, $2); ]
133 | typename
[ $$
= $1; ]
134 | EXTERN
[ $$
= bare_extern
(); ]
135 | REGISTER
[ $$
= bare_register
(); ]
136 | STATIC
[ $$
= bare_static
(); ]
140 CONST
[ $$
= bare_const
(); ]
141 | VOLATILE
[ $$
= bare_volatile
(); ]
144 declarator_list
($e, $t):
145 declarator_list
',' declarator
($e, $t)
150 /* empty */ [ if
(!$t) YYERROR; ]
151 { $$
= declare
($e, 0, $t); }
152 | ID
{ $$
= declare
($e, $1, $t); }
153 |
'(' declarator
($e, $t) ')' { $$
= $2; }
154 |
'*' cv_quals declarator
($e, $t) %prec PREFIX
155 { $$
= make_pointer
($3, $2); }
156 | declarator
'[' expr
($e) ']'
157 { $$
= make_array
($1->type
, $3); }
158 | declarator
'(' formal_arg_list
($e) ')' cv_quals
159 { $$
= build_function
($1, $3, $5); }
162 formal_arg_list
($e): { $$
= 0; }
163 | nonempty_formal_arg_list
{ $$
= $1; }
165 nonempty_formal_arg_list
($e):
166 nonempty_formal_arg_list
',' formal_arg
($e) { $$
= append_dlist
($1, $3); }
167 | formal_arg
{ $$
= build_dlist
($1); }
170 decl_specs declarator
($e,$1) { $$
= $2; }
174 expr
'+' expr
($e) { $$
= build_expr
($1, ADD
, $3); }
175 | expr
'-' expr
($e) { $$
= build_expr
($1, SUB
, $3); }
176 | expr
'*' expr
($e) { $$
= build_expr
($1, MUL
, $3); }
177 | expr
'%' expr
($e) { $$
= build_expr
($1, MOD
, $3); }
178 | expr
'/' expr
($e) { $$
= build_expr
($1, DIV
, $3); }
179 |
'*' expr
($e) %prec PREFIX
{ $$
= build_expr
(0, DEREF
, $2); }
180 | ID
{ $$
= var_expr
($e, $1); }
181 | CONSTANT
{ $$
= $1; }
186 | expr
($e) ';' [YYVALID
;] { $$
= build_expr_code
($1); }
187 | IF
'(' expr
($e) ')' THEN statement
($e) ELSE statement
($e) [YYVALID
;]
188 { $$
= build_if
($3, $6, $8); }
189 | IF
'(' expr
($e) ')' THEN statement
($e) [YYVALID
;]
190 { $$
= build_if
($3, $6, 0); }
191 | block_statement
(new_scope
($e)) [YYVALID
;]{ $$
= $1; }
194 statement_list
($e): { $$
= 0; }
195 | statement_list statement
($e) { $$
= code_append
($1, $2); }
199 '{' statement_list
($e) '}' { $$
= $2; }
203 extern
int YYLEX_DECL
();
204 extern
void YYERROR_DECL
();
206 extern Scope
*global_scope
;
208 extern Decl
* lookup
(Scope
*scope
, char *id
);
209 extern Scope
* new_scope
(Scope
*outer_scope
);
210 extern Scope
* start_fn_def
(Scope
*scope
, Decl
*fn_decl
);
211 extern
void finish_fn_def
(Decl
*fn_decl
, Code
*block
);
212 extern Type
* type_combine
(Type
*specs
, Type
*spec
);
213 extern Type
* bare_extern
(void);
214 extern Type
* bare_register
(void);
215 extern Type
* bare_static
(void);
216 extern Type
* bare_const
(void);
217 extern Type
* bare_volatile
(void);
218 extern Decl
* declare
(Scope
*scope
, char *id
, Type
*type
);
219 extern Decl
* make_pointer
(Decl
*decl
, Type
*type
);
220 extern Decl
* make_array
(Type
*type
, Expr
*expr
);
221 extern Decl
* build_function
(Decl
*decl
, Decl_List
*dlist
, Type
*type
);
222 extern Decl_List
* append_dlist
(Decl_List
*dlist
, Decl
*decl
);
223 extern Decl_List
* build_dlist
(Decl
*decl
);
224 extern Expr
* build_expr
(Expr
*left
, enum Operator op
, Expr
*right
);
225 extern Expr
* var_expr
(Scope
*scope
, char *id
);
226 extern Code
* build_expr_code
(Expr
*expr
);
227 extern Code
* build_if
(Expr
*cond_expr
, Code
*then_stmt
, Code
*else_stmt
);
228 extern Code
* code_append
(Code
*stmt_list
, Code
*stmt
);