home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 3: Developer Tools
/
Linux Cubed Series 3 - Developer Tools.iso
/
devel
/
lang
/
c
/
cxref-1.001
/
cxref-1~
/
cxref
/
parse.y
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Lex Description
|
1996-02-24
|
26.3 KB
|
1,081 lines
%{
/***************************************
$Header: /home/amb/cxref/RCS/parse.y 1.12 1996/02/24 14:53:39 amb Exp $
C Cross Referencing & Documentation tool. Version 1.0
C parser.
******************/ /******************
Original Written by N. A. Balharrie
Actions and hacks Written by Andrew M. Bishop
This file Copyright 1995,96 Andrew M. Bishop
It may be distributed under the GNU Public License, version 2, or
any higher version. See section COPYING of the GNU Public license
for conditions under which this file may be redistributed.
***************************************/
#include <string.h>
#include "parse-yy.h"
#include "cxref.h"
#include "memory.h"
static void yyerror(char *s);
/*+ When in a function header, most of the stuff can be skipped over quickly. +*/
extern int in_header;
/*+ A flag that is set to true when typedef is seen in a statement. +*/
int in_typedef=0;
/*+ The scope of the function / variable that is being examined. +*/
static int scope;
/*+ The variable must be LOCAL or EXTERNAL or GLOBAL, so this checks and sets that. +*/
#define SCOPE ( scope&(LOCAL|EXTERNAL|EXTERN_H) ? scope : scope|GLOBAL )
/*+ When in a function or a function definition, the behaviour is different. +*/
int in_function=0,in_funcdef=0;
/*+ Some strings that are needed during parsing. +*/
static char *var_name=NULL,*type_name=NULL,*su_type=NULL;
/*+ Declarations that are in the same statement share this comment. +*/
static char* common_comment=NULL;
/*+ When inside a struct / union / enum defintion, this is the depth. +*/
static int in_structunion=0;
/*+ A simple macro that reset all of the variables to the default states. +*/
#define RESET_VARS \
{ \
scope=0; \
in_typedef=0; \
in_structunion=0; \
var_name=NULL; \
type_name=NULL; \
su_type=NULL; \
common_comment=NULL; \
}
%}
%expect 25
%token IDENTIFIER LITERAL TYPE_NAME STRING_LITERAL ELLIPSES
%token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token EQ_OP NE_OP PTR_OP AND_OP OR_OP DEC_OP INC_OP LE_OP GE_OP
%token LEFT_SHIFT RIGHT_SHIFT
%token SIZEOF
%token TYPEDEF EXTERN STATIC AUTO REGISTER
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID INLINE
%token STRUCT UNION ENUM
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%start file
%%
abstract_declarator
: pointer
| pointer direct_abstract_declarator
{ $$=ConcatStrings(2,$1,$2); }
| direct_abstract_declarator
;
add_op
: '+'
| '-'
;
additive_expression
: multiplicative_expression
| additive_expression add_op multiplicative_expression
;
address_expression
: '&' unary_expression
;
array_declarator
: direct_declarator '[' ']'
{ $$=ConcatStrings(3,$1,$2,$3); }
| direct_declarator '[' constant_expression ']'
{ $$=ConcatStrings(4,$1,$2,$3,$4); }
;
assignment_expression
: conditional_expression
| unary_expression assignment_op assignment_expression
;
assignment_op
: '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;
bit_field
: ':' width
| declarator ':' width
;
bitwise_and_expression
: equality_expression
| bitwise_and_expression '&' equality_expression
;
bitwise_negation_expression
: '~' unary_expression
;
bitwise_or_expression
: bitwise_xor_expression
| bitwise_or_expression '|' bitwise_xor_expression
;
bitwise_xor_expression
: bitwise_and_expression
| bitwise_xor_expression '^' bitwise_and_expression
;
break_statement
: BREAK ';'
case_label
: CASE constant_expression
;
cast_expression
: '(' type_name ')' unary_expression
;
character_type_specifier
: CHAR
| SIGNED CHAR
{ $$=ConcatStrings(3,$1," ",$2); }
| UNSIGNED CHAR
{ $$=ConcatStrings(3,$1," ",$2); }
;
comma_expression
: assignment_expression
| comma_expression ',' assignment_expression
;
component_declaration
: type_specifier { type_name=$1; } component_declarator_list ';'
{ $$=ConcatStrings(3,$1,$3,$4); }
/* an AMB hack to allow 'const' in a struct component! */
| type_qualifier_list type_specifier { type_name=ConcatStrings(2,$1,$2); } component_declarator_list ';'
{ $$=ConcatStrings(4,$1,$2,$3,$4); }
;
component_declarator
: simple_component
| bit_field
;
component_declarator_list
: component_declarator
{ if(!in_header) SeenStructUnionComp(ConcatStrings(2,type_name,$1),in_structunion); }
| component_declarator_list ',' component_declarator
{ $$=ConcatStrings(3,$1,$2,$3);
if(!in_header) SeenStructUnionComp(ConcatStrings(2,type_name,$3),in_structunion); }
;
component_selection_expression
: direct_component_selection
| indirect_component_selection
;
/* An AMB Hack to simplify the code, 'compound_statement_body' is a new rule. */
compound_statement
: '{'
{ UpScope(); }
compound_statement_body
{ DownScope(); }
'}'
;
compound_statement_body
: /* Empty */
| inner_declaration_list
| statement_list
| inner_declaration_list statement_list
;
conditional_expression
: logical_or_expression
| logical_or_expression '?' expression ':' conditional_expression
;
conditional_statement
: if_statement
| if_else_statement
;
constant_expression
: expression
;
continue_statement
: CONTINUE ';'
;
declaration
: declaration_specifiers initialized_declarator_list ';'
/* an AMB hack to allow 'union name { ... };' */
| declaration_specifiers ';'
;
declaration_list
: declaration
| declaration_list declaration
{ $$=$2; }
;
declaration_specifiers
: declaration_specifiers1
{ if(!in_typedef) {common_comment=GetCurrentComment(); SetCurrentComment(common_comment);} }
;
declaration_specifiers1
: storage_class_specifier
| storage_class_specifier declaration_specifiers1
{ if($1) $$=ConcatStrings(3,$1," ",$2); else $$=$2; }
| type_specifier
{ type_name=$1; }
| type_specifier declaration_specifiers1
{ $$=ConcatStrings(3,$1," ",$2); }
| type_qualifier
| type_qualifier declaration_specifiers1
{ $$=ConcatStrings(3,$1," ",$2); }
;
declarator
: direct_declarator
| pointer direct_declarator
{ $$=ConcatStrings(2,$1,$2); }
;
default_label
: DEFAULT
;
direct_abstract_declarator
: '(' abstract_declarator ')'
{ $$=ConcatStrings(3,$1,$2,$3); }
| '[' ']'
{ $$=ConcatStrings(2,$1,$2); }
| direct_abstract_declarator '[' ']'
{ $$=ConcatStrings(3,$1,$2,$3); }
| '[' constant_expression ']'
{ $$=ConcatStrings(3,$1,$2,$3); }
| direct_abstract_declarator '[' constant_expression ']'
{ $$=ConcatStrings(4,$1,$2,$3,$4); }
| '(' ')'
{ $$=ConcatStrings(2,$1,$2); }
| direct_abstract_declarator '(' ')'
{ $$=ConcatStrings(3,$1,$2,$3); }
| '(' parameter_type_list ')'
{ $$=ConcatStrings(3,$1,$2,$3); }
| direct_abstract_declarator '(' parameter_type_list ')'
{ $$=ConcatStrings(4,$1,$2,$3,$4); }
;
direct_component_selection
: postfix_expression '.' name
;
direct_declarator
: simple_declarator
| '(' declarator ')'
{ if($2[0]=='*' && $2[1]==' ') { $2=&$2[1]; $2[0]='*'; }
$$=ConcatStrings(4," ",$1,$2,$3);
}
| array_declarator
| function_declarator
;
do_statement
: DO statement WHILE '(' expression ')' ';'
;
enumeration_constant
: IDENTIFIER
;
enumeration_constant_definition
: enumeration_constant
{ if(!in_header) SeenStructUnionComp($1,in_structunion); }
/* an AMB Hack, was '... = expression' but this does not parse 'int a=0,b=1,c;' (confuses it as a comma_expression) */
| enumeration_constant '=' assignment_expression
{ $$=ConcatStrings(3,$1,$2,$3); if(!in_header) SeenStructUnionComp($1,in_structunion); }
;
enumeration_definition_list
: enumeration_constant_definition
| enumeration_definition_list ',' enumeration_constant_definition
{ $$=ConcatStrings(3,$1,$2,$3); }
;
enumeration_tag
: IDENTIFIER
;
enumeration_type_definition
: ENUM '{'
{ if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
if(!in_header)
{
if(in_structunion) SeenStructUnionComp($1,in_structunion);
else SeenStructUnionStart($1);
}
in_structunion++; }
enumeration_definition_list '}'
{ in_structunion--;
if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
$$=ConcatStrings(5,$1," ",$2,$4,$5); }
| ENUM enumeration_tag '{'
{ if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
if(!in_header)
{
if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
}
in_structunion++; }
enumeration_definition_list '}'
{ in_structunion--;
if(!in_header && !in_structunion) SeenStructUnionEnd();
$$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
;
enumeration_type_reference
: ENUM enumeration_tag
{ $$=ConcatStrings(3,$1," ",$2); }
;
enumeration_type_specifier
: enumeration_type_definition
| enumeration_type_reference
;
equality_expression
: relational_expression
| equality_expression equality_op relational_expression
;
equality_op
: EQ_OP
| NE_OP
;
expression
: comma_expression
;
expression_list
: assignment_expression
| expression_list ',' assignment_expression
;
expression_statement
: expression ';'
;
field_list
: component_declaration
| field_list component_declaration
{ $$=ConcatStrings(2,$1,$2); }
;
/* AMB Hack to cope with an empty file */
file
: /* Empty */
| program
;
floating_type_specifier
: FLOAT
| DOUBLE
| LONG DOUBLE
{ $$=ConcatStrings(3,$1," ",$2); }
;
for_expressions
: ';' ';'
| expression ';' ';'
| ';' expression ';'
| ';' ';' expression
| ';' expression ';' expression
| expression ';' ';' expression
| expression ';' expression ';'
| expression ';' expression ';' expression
;
for_statement
: FOR '(' for_expressions ')' statement
;
function_call
: postfix_expression '(' ')'
| postfix_expression '(' expression_list ')'
;
/* An AMB hack, function_call_direct is entirely of my invention to avoid pointer to function */
function_call_direct
: name '(' ')'
| name '(' expression_list ')'
;
function_declarator
: function_declarator1 '(' function_declarator2 ')'
{ $$=ConcatStrings(4,$1,$2,$3,$4);
if(in_funcdef>1) in_funcdef--; }
;
/* an AMB hack to simplify the code , taken function_declarator1 out of function_declarator */
function_declarator1
: direct_declarator
{ if(!in_funcdef)
{
if(!in_typedef && !in_function && !in_header)
SeenFunctionDeclaration(var_name,SCOPE);
if(!in_function) UpScope();
}
if(!in_structunion)
in_funcdef++;
}
;
/* an AMB hack to simplify the code , taken function_declarator2 out of function_declarator */
function_declarator2
: /* Empty */ { $$=NULL; }
| parameter_type_list
| identifier_list
;
function_definition
: function_specifier1
{ in_function=1; in_funcdef=0; }
compound_statement
{ in_function=0; DownScope(); }
;
/* An AMB Hack to simplify the parse tree */
function_specifier1
: function_specifier
{ if(!in_header)
{
char *func_type,*vname=strstr($1,var_name),*pareth=strstr($1,"(");
if(pareth>vname)
{func_type=$1;pareth[0]=0;}
else
{
int open=1;
char *argbeg=strstr(&pareth[1],"("),*argend;
argbeg[1]=0;
for(argend=argbeg+2;*argend;argend++)
{
if(*argend=='(') open++;
if(*argend==')') open--;
if(!open) break;
}
func_type=ConcatStrings(2,$1,argend);
}
SeenFunctionDefinition(func_type);
}
}
;
function_specifier
: declarator
| declaration_specifiers declarator
{ $$=ConcatStrings(2,$1,$2); }
| declarator { in_function=2; } declaration_list
| declaration_specifiers declarator { in_function=2; } declaration_list
{ $$=ConcatStrings(2,$1,$2); }
;
goto_statement
: GOTO IDENTIFIER ';'
;
identifier_list
: IDENTIFIER
| identifier_list ',' IDENTIFIER
{ $$=ConcatStrings(3,$1,$2,$3); }
;
if_else_statement
: IF '(' expression ')' statement ELSE statement
;
if_statement
: IF '(' expression ')' statement
;
indirect_component_selection
: postfix_expression PTR_OP name
;
indirection_expression
: '*' unary_expression
;
/* an AMB hack to allow simplification of the code , put initialized_declarator1 in initialized_declarator_list */
initialized_declarator1
: initialized_declarator
{
if(!in_function && !in_funcdef && !in_structunion)
{
char* specific_comment=GetCurrentComment();
if(!common_comment) SetCurrentComment(specific_comment); else
if(!specific_comment) SetCurrentComment(common_comment); else
if(common_comment!=specific_comment) SetCurrentComment(ConcatStrings(3,common_comment," ",specific_comment)); else
SetCurrentComment(common_comment);
}
if(in_typedef)
{
SeenTypedefName(var_name);
if(!in_header)
SeenTypedef(var_name,ConcatStrings(2,su_type?su_type:type_name,$1));
}
else
if(in_function==2 && in_funcdef)
{ SeenFunctionArg(ConcatStrings(2,type_name,$1)); SeenScopeVariable(var_name); }
else
if(in_function)
SeenScopeVariable(var_name);
else
{
char* vname=strstr($1,var_name);
if(vname[strlen(var_name)]=='(')
SeenFunctionProto(var_name);
else
if(!in_structunion && (!in_header || ((in_header==LOCAL)&&(scope&EXTERN_H))))
SeenVariableDefinition(var_name,ConcatStrings(2,type_name,$1),SCOPE);
}
if(in_funcdef && in_function!=2) { in_funcdef=0; if(!in_function) DownScope(); }
}
;
initialized_declarator
: declarator
| declarator initializer_part
;
initialized_declarator_list
: initialized_declarator1
| initialized_declarator_list ',' initialized_declarator1
;
initializer
/* an AMB Hack, was ': expression' but this does not parse 'int a=0,b;' (confuses it as a comma_expression) */
: assignment_expression
| '{' initializer_list '}'
| '{' initializer_list ',' '}'
;
initializer_list
: initializer
| initializer_list ',' initializer
;
initializer_part
: '=' initializer
;
inner_declaration_list
: declaration_list
;
integer_type_specifier
: signed_type_specifier
| unsigned_type_specifier
| character_type_specifier
;
iterative_statement
: do_statement
| while_statement
| for_statement
;
label
: named_label
| case_label
| default_label
;
labeled_statement
: label ':' statement
logical_and_expression
: bitwise_or_expression
| logical_and_expression AND_OP bitwise_or_expression
;
logical_negation_expression
: '!' unary_expression
;
logical_or_expression
: logical_and_expression
| logical_or_expression OR_OP logical_and_expression
;
mult_op
: '*'
| '/'
| '%'
;
multiplicative_expression
: unary_expression
| multiplicative_expression mult_op unary_expression
;
name
: IDENTIFIER
;
named_label
: IDENTIFIER
;
null_statement
: ';'
;
parameter_declaration
: declaration_specifiers declarator
{ $$=ConcatStrings(2,$1,$2); }
| declaration_specifiers
| declaration_specifiers abstract_declarator
{ $$=ConcatStrings(2,$1,$2); }
;
parameter_list
: parameter_declaration
{ if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($1); }
| parameter_list ',' parameter_declaration
{ if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($3);
$$=ConcatStrings(3,$1,$2,$3); }
;
parameter_type_list
: parameter_list
| parameter_list ',' ELLIPSES
{ if(!in_header && !in_typedef && !in_function && in_funcdef==1) SeenFunctionArg($3);
$$=ConcatStrings(3,$1,$2,$3); }
;
parenthesized_expression
: '(' expression ')'
;
pointer
: '*'
| '*' pointer1
{ $$=ConcatStrings(2,$1,$2); }
;
pointer1
: type_qualifier_list
| pointer
| type_qualifier_list pointer
{ $$=ConcatStrings(2,$1,$2); }
;
postdecrement_expression
: postfix_expression DEC_OP
;
postfix_expression
: primary_expression
| subscript_expression
| component_selection_expression
| function_call
| function_call_direct
{ if(!in_header && !IsAScopeVariable($1)) SeenFunctionCall($1); }
| postincrement_expression
| postdecrement_expression
;
postincrement_expression
: postfix_expression INC_OP
;
predecrement_expression
: DEC_OP unary_expression
;
preincrement_expression
: INC_OP unary_expression
;
primary_expression
: name
{ if(!in_header) CheckFunctionVariableRef($1,in_function); }
| LITERAL
| string_literal
| parenthesized_expression
;
program
: top_level_declaration
| program top_level_declaration
;
relational_expression
: shift_expression
| relational_expression relational_op shift_expression
;
relational_op
: '<'
| LE_OP
| '>'
| GE_OP
;
return_statement
: RETURN ';'
| RETURN expression ';'
;
shift_expression
: additive_expression
| shift_expression shift_op additive_expression
;
shift_op
: LEFT_SHIFT
| RIGHT_SHIFT
;
signed_type_specifier
: SHORT
| SHORT INT
{ $$=ConcatStrings(3,$1," ",$2); }
| INT
| LONG
| LONG INT
{ $$=ConcatStrings(3,$1," ",$2); }
| LONG LONG
{ $$=ConcatStrings(3,$1," ",$2); }
| SIGNED
| SIGNED SHORT
{ $$=ConcatStrings(3,$1," ",$2); }
| SIGNED SHORT INT
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
| SIGNED INT
{ $$=ConcatStrings(3,$1," ",$2); }
| SIGNED LONG
{ $$=ConcatStrings(3,$1," ",$2); }
| SIGNED LONG INT
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
| SIGNED LONG LONG
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
;
simple_component
: declarator
;
simple_declarator
: IDENTIFIER
{ $$=ConcatStrings(2," ",$1); if(!in_funcdef) var_name=$1; else SeenScopeVariable($1); }
;
sizeof_expression
: SIZEOF '(' type_name ')'
| SIZEOF unary_expression
;
statement
: expression_statement
| labeled_statement
| compound_statement
| conditional_statement
| iterative_statement
| switch_statement
| break_statement
| continue_statement
| return_statement
| goto_statement
| null_statement
;
statement_list
: statement
| statement_list statement
;
storage_class_specifier
: AUTO
{ $$=NULL; }
| EXTERN
{ $$=NULL; if(in_header) scope |= EXTERN_H; else scope |= EXTERNAL; }
| REGISTER
{ $$=NULL; }
| STATIC
{ $$=NULL; scope |= LOCAL; }
| TYPEDEF
{ in_typedef=1; if(!in_header) SeenTypedef(NULL,NULL);
common_comment=GetCurrentComment(); SetCurrentComment(common_comment); }
/* an AMB hack to allow inline functions */
| INLINE
{ $$=NULL; scope |= INLINED; }
;
string_literal
: STRING_LITERAL
/* an AMB hack to allow '"foo" "bar"' to be recognised as "foobar" */
| string_literal STRING_LITERAL
;
structure_tag
: IDENTIFIER
/* an AMB hack to allow 'typedef struct foo foo ; typedef struct foo bar' */
| TYPE_NAME
;
structure_type_definition
: STRUCT '{'
{ if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
if(!in_header)
{
if(in_structunion) SeenStructUnionComp($1,in_structunion);
else SeenStructUnionStart($1);
}
in_structunion++; }
field_list '}'
{ in_structunion--;
if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
$$=ConcatStrings(5,$1," ",$2,$4,$5); }
| STRUCT structure_tag '{'
{ if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
if(!in_header)
{
if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
}
in_structunion++; }
field_list '}'
{ in_structunion--;
if(!in_header && !in_structunion) SeenStructUnionEnd();
$$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
;
structure_type_reference
: STRUCT structure_tag
{ $$=ConcatStrings(3,$1," ",$2); }
;
structure_type_specifier
: structure_type_definition
| structure_type_reference
;
subscript_expression
: postfix_expression '[' expression ']'
;
switch_statement
: SWITCH '(' expression ')' statement
;
top_level_declaration
: declaration
{ RESET_VARS }
| function_definition
{ RESET_VARS }
;
type_name
: declaration_specifiers
| declaration_specifiers abstract_declarator
{ $$=ConcatStrings(2,$1,$2); }
;
type_qualifier
: CONST
{ $$=ConcatStrings(2,$1," "); }
| VOLATILE
{ $$=ConcatStrings(2,$1," "); }
;
type_qualifier_list
: type_qualifier
| type_qualifier_list type_qualifier
{ $$=ConcatStrings(2,$1,$2); }
;
type_specifier
: enumeration_type_specifier
| floating_type_specifier
| integer_type_specifier
| structure_type_specifier
| typedef_name
| union_type_specifier
| void_type_specifier
;
typedef_name
: TYPE_NAME
;
unary_expression
: postfix_expression
| cast_expression
| sizeof_expression
| unary_minus_expression
| unary_plus_expression
| logical_negation_expression
| bitwise_negation_expression
| address_expression
| indirection_expression
| preincrement_expression
| predecrement_expression
;
unary_minus_expression
: '-' unary_expression
;
unary_plus_expression
: '+' unary_expression
;
union_tag
: IDENTIFIER
/* an AMB hack to allow 'typedef union foo foo ; typedef union foo bar' */
| TYPE_NAME
;
union_type_definition
: UNION '{'
{ if(!in_structunion) su_type=ConcatStrings(2,$1," {...}");
if(!in_header)
{
if(in_structunion) SeenStructUnionComp($1,in_structunion);
else SeenStructUnionStart($1);
}
in_structunion++; }
field_list '}'
{ in_structunion--;
if(!in_header && !in_structunion && in_typedef) SeenStructUnionEnd();
$$=ConcatStrings(5,$1," ",$2,$4,$5); }
| UNION union_tag '{'
{ if(!in_structunion) su_type = ConcatStrings(3,$1," ",$2);
if(!in_header)
{
if(in_structunion) SeenStructUnionComp(ConcatStrings(3,$1," ",$2),in_structunion);
else SeenStructUnionStart(ConcatStrings(3,$1," ",$2));
}
in_structunion++; }
field_list '}'
{ in_structunion--;
if(!in_header && !in_structunion) SeenStructUnionEnd();
$$=ConcatStrings(7,$1," ",$2," ",$3,$5,$6);}
;
union_type_reference
: UNION union_tag
{ $$=ConcatStrings(3,$1," ",$2); }
;
union_type_specifier
: union_type_definition
| union_type_reference
;
unsigned_type_specifier
: UNSIGNED SHORT INT
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
| UNSIGNED INT
{ $$=ConcatStrings(3,$1," ",$2); }
| UNSIGNED LONG INT
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
| UNSIGNED SHORT
{ $$=ConcatStrings(3,$1," ",$2); }
| UNSIGNED
| UNSIGNED LONG
{ $$=ConcatStrings(3,$1," ",$2); }
| UNSIGNED LONG LONG
{ $$=ConcatStrings(5,$1," ",$2," ",$3); }
;
void_type_specifier
: VOID
;
while_statement
: WHILE '(' expression ')' statement
;
width
: expression
;
%%
#include <stdio.h>
static void yyerror( char *s )
{
int i;
fflush(stdout);
fprintf(stderr,"cxref: Error parsing %s\n\n",s);
#ifdef YYDEBUG
/*
fprintf(stderr,"in_function=%2d, in_funcdef=%2d\n",in_function,in_funcdef);
fprintf(stderr,"var_name='%s'\n",var_name);
fprintf(stderr,"in_typedef=%2d, in_structunion=%2d type_name='%s' su_type='%s'\n",in_typedef,in_structunion,type_name,su_type);
*/
fprintf(stderr,"\nThe current and next 10 symbols are:\n");
#ifdef YYBISON
fprintf(stderr,"%3d : %16s : %s\n",yychar,yychar>255?yytname[yychar-255]:"",yylval);
for(i=0;i<10;i++)
{
int yyl=yylex();
if(!yyl)
{fprintf(stderr,"END OF FILE\n");break;}
fprintf(stderr,"%3d : %16s : %s\n",yyl,yyl>255?yytname[yyl-255]:"",yylval);
}
#else
fprintf(stderr,"%3d : %s\n",yychar,yylval);
for(i=0;i<10;i++)
{
int yyl=yylex();
if(!yyl)
{fprintf(stderr,"END OF FILE\n");break;}
fprintf(stderr,"%3d : %s\n",yyl,yylval);
}
#endif
#endif
exit(2);
}