From: "Christopher Nelson" To: Subject: Re: Bison and [f]lexical tie-ins Date: Tue, 13 Jul 1999 17:53:39 -0600 Message-ID: <01becd8a$ee8001e0$LocalHost@thendren> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 4.71.1712.3 X-MimeOLE: Produced By Microsoft MimeOLE V4.71.1712.3 Reply-To: djgpp AT delorie DOT com > The manner you described for your lexical tie-in, is not *exactly* the >way it should work. From your text, it sounds as if you're returning the >type of the id? or perhaps a different token? depending on what you see the >id as. This is ambiguous, and creates the errors you described. > > A better approach is to do the following: > > >{ID} yylvalue.id = install_id(yytext); return ID; > > > In this case, the lexical tie-in makes sure that the lexme that >corresponds to this particular id is in the symbol table to start with - but >without a type. Or more precisely, type_none. If the lexme DOES match a >symbol already in the table, that symbol is returned, otherwise the newly >created symbol is returned. > > Inside the parser you should check to see what the type of the symbol is >(pretending that $1 is your ID token): > > if (lookup($1)==TYPE_NONE) addtype($1, the_type); > else /* this lexeme exists as a symbol of a different type, you'll >have to create a > new symbol */ { $1=duplicate_id($1); addtype($1, >the_type); } > > This follows C's most-closely nested rule by allowing you to get the >last-declared version of a symbol first (assuming that your storage >structure is a list of some sort) by starting at the head of the list and >seeking towards the end. > > You should, in addition, have some sort of prologue code on the same >level as the parameter list nonterminal that sets a global-variable called >type so that you can use it, or alternatively (and more flexible and >powerful, though a bit more difficult), construct a small type-tree that >contains a list or perhaps a stack of the parameters, then walk the tree, or >consider the stack until it's empty, applying the above logic to each of >them. > > In other words: > >parameter: id { $$=$1; } > ; > >parameter_list: parameter { push($1, >parmstack); } > parameter_list ',' parameter { push($1, >parmstack); } > ; > >decl_prologue: var_type { $$=$1; } > ; > >declaration: decl_prologue parameter_list ';' { symentry *sym; > >while((sym==pop(parmstack)) > >{ /* consider each one as shown > >above, deciding what to do with > >it based on the type rules. */ > > } > } > > > This has the added benefit of then allowing you to warn about >shadow-variables, and finding scope rules and type sets, rather than just >returning the first thing you see. > > -={C}=- > > > >