2 * Wrc preprocessor syntax analysis
4 * Copyright 1999-2000 Bertho A. Stultiens (BS)
6 * 24-Apr-2000 BS Restructured the lot to fit the new scanner
7 * and reintegrate into the wine-tree.
8 * 01-Jan-2000 BS FIXME: win16 preprocessor calculates with
9 * 16 bit ints and overflows...?
10 * 26-Dec-1999 BS Started this file
30 #define UNARY_OP(r, v, OP) \
33 case cv_sint
: r.val.si
= OP v.val.si
; break
; \
34 case cv_uint
: r.val.ui
= OP v.val.ui
; break
; \
35 case cv_slong
: r.val.sl
= OP v.val.sl
; break
; \
36 case cv_ulong
: r.val.ul
= OP v.val.ul
; break
; \
37 case cv_sll
: r.val.sll
= OP v.val.sll
; break
; \
38 case cv_ull
: r.val.ull
= OP v.val.ull
; break
; \
41 #define cv_signed(v) ((v.type & FLAG_SIGNED) != 0)
43 #define BIN_OP_INT(r, v1, v2, OP) \
45 if
(cv_signed
(v1
) && cv_signed
(v2
)) \
46 r.val.si
= v1.val.si OP v2.val.si
; \
47 else if
(cv_signed
(v1
) && !cv_signed
(v2
)) \
48 r.val.si
= v1.val.si OP v2.val.ui
; \
49 else if
(!cv_signed
(v1
) && cv_signed
(v2
)) \
50 r.val.ui
= v1.val.ui OP v2.val.si
; \
52 r.val.ui
= v1.val.ui OP v2.val.ui
;
54 #define BIN_OP_LONG(r, v1, v2, OP) \
56 if
(cv_signed
(v1
) && cv_signed
(v2
)) \
57 r.val.sl
= v1.val.sl OP v2.val.sl
; \
58 else if
(cv_signed
(v1
) && !cv_signed
(v2
)) \
59 r.val.sl
= v1.val.sl OP v2.val.ul
; \
60 else if
(!cv_signed
(v1
) && cv_signed
(v2
)) \
61 r.val.ul
= v1.val.ul OP v2.val.sl
; \
63 r.val.ul
= v1.val.ul OP v2.val.ul
;
65 #define BIN_OP_LONGLONG(r, v1, v2, OP) \
67 if
(cv_signed
(v1
) && cv_signed
(v2
)) \
68 r.val.sll
= v1.val.sll OP v2.val.sll
; \
69 else if
(cv_signed
(v1
) && !cv_signed
(v2
)) \
70 r.val.sll
= v1.val.sll OP v2.val.ull
; \
71 else if
(!cv_signed
(v1
) && cv_signed
(v2
)) \
72 r.val.ull
= v1.val.ull OP v2.val.sll
; \
74 r.val.ull
= v1.val.ull OP v2.val.ull
;
76 #define BIN_OP(r, v1, v2, OP) \
77 switch
(v1.type
& SIZE_MASK
) \
79 case SIZE_INT
: BIN_OP_INT
(r
, v1
, v2
, OP
); break
; \
80 case SIZE_LONG
: BIN_OP_LONG
(r
, v1
, v2
, OP
); break
; \
81 case SIZE_LONGLONG
: BIN_OP_LONGLONG
(r
, v1
, v2
, OP
); break
; \
82 default
: internal_error
(__FILE__
, __LINE__
, "Invalid type indicator (0x%04x)", v1.type
); \
89 static int boolean
(cval_t
*v
);
90 static void promote_equal_size
(cval_t
*v1
, cval_t
*v2
);
91 static void cast_to_sint
(cval_t
*v
);
92 static void cast_to_uint
(cval_t
*v
);
93 static void cast_to_slong
(cval_t
*v
);
94 static void cast_to_ulong
(cval_t
*v
);
95 static void cast_to_sll
(cval_t
*v
);
96 static void cast_to_ull
(cval_t
*v
);
97 static marg_t
*new_marg
(char *str
, def_arg_t type
);
98 static marg_t
*add_new_marg
(char *str
, def_arg_t type
);
99 static int marg_index
(char *id
);
100 static mtext_t
*new_mtext
(char *str
, int idx
, def_exp_t type
);
101 static mtext_t
*combine_mtext
(mtext_t
*tail
, mtext_t
*mtp
);
102 static char *merge_text
(char *s1
, char *s2
);
107 static marg_t
**macro_args
; /* Macro parameters array while parsing */
108 static int nmacro_args
;
126 %token tIF tIFDEF tIFNDEF tELSE tELIF tENDIF tDEFINED tNL
127 %token tINCLUDE tLINE tGCCLINE tERROR tWARNING tPRAGMA tPPIDENT
128 %token tUNDEF tMACROEND tCONCAT tELIPSIS tSTRINGIZE
129 %token
<cptr
> tIDENT tLITERAL tMACRO tDEFINE
130 %token
<cptr
> tDQSTRING tSQSTRING tIQSTRING
133 %token
<ulong
> tULONG
134 %token
<slong
> tSLONG
135 %token
<ull
> tULONGLONG
136 %token
<sll
> tSLONGLONG
144 %left
'<' tLTE
'>' tGTE
145 %left tLSHIFT tRSHIFT
151 %type
<marg
> emargs margs
152 %type
<mtext
> opt_mtexts mtexts mtext
153 %type
<sint
> nums allmargs
154 %type
<cptr
> opt_text text
157 **************************************************************************
158 * The parser starts here
159 **************************************************************************
164 pp_file
: /* Empty */
165 | pp_file preprocessor
169 : tINCLUDE tDQSTRING tNL
{ do_include
($2, 1); }
170 | tINCLUDE tIQSTRING tNL
{ do_include
($2, 0); }
171 | tIF pp_expr tNL
{ next_if_state
(boolean
(&$2)); }
172 | tIFDEF tIDENT tNL
{ next_if_state
(pplookup
($2) != NULL
); free
($2); }
173 | tIFNDEF tIDENT tNL
{
174 int t
= pplookup
($2) == NULL
;
175 if
(include_state
== 0 && t
&& !seen_junk
)
179 include_ifdepth
= get_if_depth
();
181 else if
(include_state
!= 1)
189 if
(debuglevel
& DEBUGLEVEL_PPMSG
)
190 fprintf
(stderr
, "tIFNDEF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name
, line_number
, include_state
, include_ppp
, include_ifdepth
);
192 | tELIF pp_expr tNL
{
193 if_state_t s
= pop_if
();
201 push_if
(boolean
(&$2) ? if_true
: if_false
);
208 pperror
("#elif cannot follow #else");
210 internal_error
(__FILE__
, __LINE__
, "Invalid if_state (%d) in #elif directive", s
);
214 if_state_t s
= pop_if
();
218 push_if
(if_elsefalse
);
224 push_if
(if_elsetrue
);
231 pperror
("#else clause already defined");
233 internal_error
(__FILE__
, __LINE__
, "Invalid if_state (%d) in #else directive", s
);
238 if
(include_ifdepth
== get_if_depth
() && include_state
== 1)
243 else if
(include_state
!= 1)
247 if
(debuglevel
& DEBUGLEVEL_PPMSG
)
248 fprintf
(stderr
, "tENDIF: %s:%d: include_state=%d, include_ppp='%s', include_ifdepth=%d\n", input_name
, line_number
, include_state
, include_ppp
, include_ifdepth
);
250 | tUNDEF tIDENT tNL
{ del_define
($2); free
($2); }
251 | tDEFINE opt_text tNL
{ add_define
($1, $2); }
252 | tMACRO res_arg allmargs tMACROEND opt_mtexts tNL
{
253 add_macro
($1, macro_args
, nmacro_args
, $5);
255 | tLINE tSINT tDQSTRING tNL
{ fprintf
(ppout
, "# %d %s\n", $2 - 1, $3); free
($3); }
256 | tGCCLINE tDQSTRING nums tNL
{ fprintf
(ppout
, "# %d %s\n", $3 - 1, $2); free
($2); }
257 | tGCCLINE tNL
/* The null-token */
258 | tERROR opt_text tNL
{ pperror
("#error directive: '%s'", $2); if
($2) free
($2); }
259 | tWARNING opt_text tNL
{ ppwarning
("#warning directive: '%s'", $2); if
($2) free
($2); }
260 | tPRAGMA opt_text tNL
{ if
(pedantic
) ppwarning
("#pragma ignored (arg: '%s')", $2); if
($2) free
($2); }
261 | tPPIDENT opt_text tNL
{ if
(pedantic
) ppwarning
("#ident ignored (arg: '%s')", $2); if
($2) free
($2); }
265 opt_text: /* Empty */ { $$
= NULL
; }
269 text
: tLITERAL
{ $$
= $1; }
270 | tDQSTRING
{ $$
= $1; }
271 | tSQSTRING
{ $$
= $1; }
272 | text tLITERAL
{ $$
= merge_text
($1, $2); }
273 | text tDQSTRING
{ $$
= merge_text
($1, $2); }
274 | text tSQSTRING
{ $$
= merge_text
($1, $2); }
277 res_arg
: /* Empty */ { macro_args
= NULL
; nmacro_args
= 0; }
280 nums
: tSINT
{ $$
= $1; }
281 | nums tSINT
/* Ignore */
284 allmargs: /* Empty */ { $$
= 0; macro_args
= NULL
; nmacro_args
= 0; }
285 | emargs
{ $$
= nmacro_args
; }
288 emargs
: margs
{ $$
= $1; }
289 | margs
',' tELIPSIS
{ $$
= add_new_marg
(NULL
, arg_list
); nmacro_args
*= -1; }
292 margs
: margs
',' tIDENT
{ $$
= add_new_marg
($3, arg_single
); }
293 | tIDENT
{ $$
= add_new_marg
($1, arg_single
); }
297 : /* Empty */ { $$
= NULL
; }
299 for
($$
= $1; $$
&& $$
->prev
; $$
= $$
->prev
)
304 mtexts
: mtext
{ $$
= $1; }
305 | mtexts mtext
{ $$
= combine_mtext
($1, $2); }
308 mtext
: tLITERAL
{ $$
= new_mtext
($1, 0, exp_text
); }
309 | tDQSTRING
{ $$
= new_mtext
($1, 0, exp_text
); }
310 | tSQSTRING
{ $$
= new_mtext
($1, 0, exp_text
); }
311 | tCONCAT
{ $$
= new_mtext
(NULL
, 0, exp_concat
); }
312 | tSTRINGIZE tIDENT
{
313 int mat
= marg_index
($2);
315 pperror
("Stringification identifier must be an argument parameter");
316 $$
= new_mtext
(NULL
, mat
, exp_stringize
);
319 int mat
= marg_index
($1);
321 $$
= new_mtext
(NULL
, mat
, exp_subst
);
323 $$
= new_mtext
($1, 0, exp_text
);
327 pp_expr
: tSINT
{ $$.type
= cv_sint
; $$.val.si
= $1; }
328 | tUINT
{ $$.type
= cv_uint
; $$.val.ui
= $1; }
329 | tSLONG
{ $$.type
= cv_slong
; $$.val.sl
= $1; }
330 | tULONG
{ $$.type
= cv_ulong
; $$.val.ul
= $1; }
331 | tSLONGLONG
{ $$.type
= cv_sll
; $$.val.sl
= $1; }
332 | tULONGLONG
{ $$.type
= cv_ull
; $$.val.ul
= $1; }
333 | tDEFINED tIDENT
{ $$.type
= cv_sint
; $$.val.si
= pplookup
($2) != NULL
; }
334 | tDEFINED
'(' tIDENT
')' { $$.type
= cv_sint
; $$.val.si
= pplookup
($3) != NULL
; }
335 | tIDENT
{ $$.type
= cv_sint
; $$.val.si
= 0; }
336 | pp_expr tLOGOR pp_expr
{ $$.type
= cv_sint
; $$.val.si
= boolean
(&$1) || boolean
(&$3); }
337 | pp_expr tLOGAND pp_expr
{ $$.type
= cv_sint
; $$.val.si
= boolean
(&$1) && boolean
(&$3); }
338 | pp_expr tEQ pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, ==) }
339 | pp_expr tNE pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, !=) }
340 | pp_expr
'<' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, <) }
341 | pp_expr
'>' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, >) }
342 | pp_expr tLTE pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, <=) }
343 | pp_expr tGTE pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, >=) }
344 | pp_expr
'+' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, +) }
345 | pp_expr
'-' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, -) }
346 | pp_expr
'^' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, ^
) }
347 | pp_expr
'&' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, &) }
348 | pp_expr
'|' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, |
) }
349 | pp_expr
'*' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, *) }
350 | pp_expr
'/' pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, /) }
351 | pp_expr tLSHIFT pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, <<) }
352 | pp_expr tRSHIFT pp_expr
{ promote_equal_size
(&$1, &$3); BIN_OP
($$
, $1, $3, >>) }
353 |
'+' pp_expr
{ $$
= $2; }
354 |
'-' pp_expr
{ UNARY_OP
($$
, $2, -) }
355 |
'~' pp_expr
{ UNARY_OP
($$
, $2, ~
) }
356 |
'!' pp_expr
{ $$.type
= cv_sint
; $$.val.si
= !boolean
(&$2); }
357 |
'(' pp_expr
')' { $$
= $2; }
358 | pp_expr
'?' pp_expr
':' pp_expr
{ $$
= boolean
(&$1) ?
$3 : $5; }
364 **************************************************************************
366 **************************************************************************
369 static void cast_to_sint
(cval_t
*v
)
375 case cv_slong
: v
->val.si
= v
->val.sl
; break
;
376 case cv_ulong
: v
->val.si
= v
->val.ul
; break
;
377 case cv_sll
: v
->val.si
= v
->val.sll
; break
;
378 case cv_ull
: v
->val.si
= v
->val.ull
; break
;
383 static void cast_to_uint
(cval_t
*v
)
389 case cv_slong
: v
->val.ui
= v
->val.sl
; break
;
390 case cv_ulong
: v
->val.ui
= v
->val.ul
; break
;
391 case cv_sll
: v
->val.ui
= v
->val.sll
; break
;
392 case cv_ull
: v
->val.ui
= v
->val.ull
; break
;
397 static void cast_to_slong
(cval_t
*v
)
401 case cv_sint
: v
->val.sl
= v
->val.si
; break
;
402 case cv_uint
: v
->val.sl
= v
->val.ui
; break
;
403 case cv_slong
: break
;
404 case cv_ulong
: break
;
405 case cv_sll
: v
->val.sl
= v
->val.sll
; break
;
406 case cv_ull
: v
->val.sl
= v
->val.ull
; break
;
411 static void cast_to_ulong
(cval_t
*v
)
415 case cv_sint
: v
->val.ul
= v
->val.si
; break
;
416 case cv_uint
: v
->val.ul
= v
->val.ui
; break
;
417 case cv_slong
: break
;
418 case cv_ulong
: break
;
419 case cv_sll
: v
->val.ul
= v
->val.sll
; break
;
420 case cv_ull
: v
->val.ul
= v
->val.ull
; break
;
425 static void cast_to_sll
(cval_t
*v
)
429 case cv_sint
: v
->val.sll
= v
->val.si
; break
;
430 case cv_uint
: v
->val.sll
= v
->val.ui
; break
;
431 case cv_slong
: v
->val.sll
= v
->val.sl
; break
;
432 case cv_ulong
: v
->val.sll
= v
->val.ul
; break
;
439 static void cast_to_ull
(cval_t
*v
)
443 case cv_sint
: v
->val.ull
= v
->val.si
; break
;
444 case cv_uint
: v
->val.ull
= v
->val.ui
; break
;
445 case cv_slong
: v
->val.ull
= v
->val.sl
; break
;
446 case cv_ulong
: v
->val.ull
= v
->val.ul
; break
;
454 static void promote_equal_size
(cval_t
*v1
, cval_t
*v2
)
456 #define cv_sizeof(v) ((int)(v->type & SIZE_MASK))
457 int s1
= cv_sizeof
(v1
);
458 int s2
= cv_sizeof
(v2
);
467 case cv_sint
: cast_to_sint
(v2
); break
;
468 case cv_uint
: cast_to_uint
(v2
); break
;
469 case cv_slong
: cast_to_slong
(v2
); break
;
470 case cv_ulong
: cast_to_ulong
(v2
); break
;
471 case cv_sll
: cast_to_sll
(v2
); break
;
472 case cv_ull
: cast_to_ull
(v2
); break
;
479 case cv_sint
: cast_to_sint
(v1
); break
;
480 case cv_uint
: cast_to_uint
(v1
); break
;
481 case cv_slong
: cast_to_slong
(v1
); break
;
482 case cv_ulong
: cast_to_ulong
(v1
); break
;
483 case cv_sll
: cast_to_sll
(v1
); break
;
484 case cv_ull
: cast_to_ull
(v1
); break
;
490 static int boolean
(cval_t
*v
)
494 case cv_sint
: return v
->val.si
!= (int)0;
495 case cv_uint
: return v
->val.ui
!= (unsigned int)0;
496 case cv_slong
: return v
->val.sl
!= (long)0;
497 case cv_ulong
: return v
->val.ul
!= (unsigned long)0;
498 case cv_sll
: return v
->val.sll
!= (wrc_sll_t
)0;
499 case cv_ull
: return v
->val.ull
!= (wrc_ull_t
)0;
504 static marg_t
*new_marg
(char *str
, def_arg_t type
)
506 marg_t
*ma
= (marg_t
*)xmalloc
(sizeof
(marg_t
));
512 static marg_t
*add_new_marg
(char *str
, def_arg_t type
)
514 marg_t
*ma
= new_marg
(str
, type
);
516 macro_args
= (marg_t
**)xrealloc
(macro_args
, nmacro_args
* sizeof
(macro_args
[0]));
517 macro_args
[nmacro_args
-1] = ma
;
521 static int marg_index
(char *id
)
524 for
(t
= 0; t
< nmacro_args
; t
++)
526 if
(!strcmp
(id
, macro_args
[t
]->arg
))
529 return t
< nmacro_args ? t
: -1;
532 static mtext_t
*new_mtext
(char *str
, int idx
, def_exp_t type
)
534 mtext_t
*mt
= (mtext_t
*)xmalloc
(sizeof
(mtext_t
));
536 mt
->subst.argidx
= idx
;
538 mt
->subst.text
= str
;
543 static mtext_t
*combine_mtext
(mtext_t
*tail
, mtext_t
*mtp
)
551 if
(tail
->type
== exp_text
&& mtp
->type
== exp_text
)
553 tail
->subst.text
= xrealloc
(tail
->subst.text
, strlen
(tail
->subst.text
)+strlen
(mtp
->subst.text
)+1);
554 strcat
(tail
->subst.text
, mtp
->subst.text
);
555 free
(mtp
->subst.text
);
560 if
(tail
->type
== exp_concat
&& mtp
->type
== exp_concat
)
566 if
(tail
->type
== exp_concat
&& mtp
->type
== exp_text
)
568 int len
= strlen
(mtp
->subst.text
);
571 /* FIXME: should delete space from head of string */
572 if
(isspace
(mtp
->subst.text
[len
-1]))
573 mtp
->subst.text
[--len
] = '\0';
580 free
(mtp
->subst.text
);
586 if
(tail
->type
== exp_text
&& mtp
->type
== exp_concat
)
588 int len
= strlen
(tail
->subst.text
);
591 if
(isspace
(tail
->subst.text
[len
-1]))
592 tail
->subst.text
[--len
] = '\0';
599 mtp
->prev
= tail
->prev
;
600 mtp
->next
= tail
->next
;
602 tail
->prev
->next
= mtp
;
603 free
(tail
->subst.text
);
615 static char *merge_text
(char *s1
, char *s2
)
619 s1
= xrealloc
(s1
, l1
+l2
+1);
620 memcpy
(s1
+l1
, s2
, l2
+1);