help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to get the text corresponding to a bison rule


From: Laurence Finston
Subject: Re: How to get the text corresponding to a bison rule
Date: Fri, 28 Nov 2008 15:15:36 +0100 (CET)

> Basically, I want to derive information from it. For example, if I got a
> matrix like [[1,2],[3,4]], I want to find the dimensions of it. 

It's not that difficult to do this sort of thing.  

I almost always call the object I pass to Bison along with the parameter 
for `yylex' `scanner_node' and it is of type `Scanner_Node', whereby
`Scanner_Node' is a typedef for  
`struct Scanner_Type *'.  When I've written my own version of `yylex' 
(which isn't hard to do, if you don't need or want low-level 
scanning using regular expressions), one can just pass a `Scanner_Node' 
(cast to `void*') to `yyparse' and `yylex' without the extra rigamarole.  
However, it's not that difficult to attach it to the `yylex' parameter 
when using Flex;  I just would have to look up how I did this, because I 
don't know off the top of my head.

I believe there's something fairly new in Bison where one can declare
the type one passes as a parameter to `yyparse', so one doesn't need
to cast to and from `void*' all the time.  However, I couldn't get
this to work when using `yylex' as well.  Perhaps it is possible, but
casting to and from `void*' is not a big problem.

The point of all this is that one can declare `Scanner_Type' (or whatever you 
choose to call it) something like this:

struct Scanner_Type
{

   int bracket_counter;

   <other data members>

   <member function declarations>

};

Then, in the constructor or constructors for `Scanner_Type', set 
`bracket_counter' to 0, e.g.,

Scanner_Type::Scanner_Type(void)
{
   bracket_counter = 0;

   return;
}

Of course, if you're using C, you'll have to write an `init' function to 
initialize your `Scanner_Type' and ensure that it's called when you 
allocate memory for each `Scanner_Type'.  If you have multiple calls
to `yyparse' with a thread for each one, you will have multiple
`Scanner_Types' (or `Scanner_Nodes'): one for each thread and instance
of `yyparse'.  Then, all you have to do is increment
`scanner_node->bracket_ctr' when `yylex' produces a `[' (a `LEFT_BRACKET'
token) and decrement it when it produces a `]' (a `RIGHT_BRACKET'
token).  For what it's worth, I always use names for tokens and never
use characters or strings, but that's purely a matter of taste.

You'll have to keep track of when you get left and right brackets, but 
I'm as sure as I can be that it can be done in the same way, without 
actually having ever implemented this myself.  I've got variables with
multiple dimensions, where the brackets don't have to all be together, 
in the GNU 3DLDF language (based on Knuth's METAFONT language),
e.g.,  `a[]bc[]def[][]g' would be a valid declaration,
but I don't actually specifically keep track of how many
dimensions such a variable has.  I could get this information at a
later time if I needed it, though.

I hope this is of some help.

Laurence 

> 
> Basically, I want to derive information from it. For example, if I got a
> matrix like [[1,2],[3,4]], I want to find the dimensions of it. The thing
> is, taht I had already a pretty good function for doing this, when I had
> manipulating the expression without bison. now with bison, if I want to the
> same thing, i have to make it from the start. I will try to do it just with
> bison, but if it gets too complicated, I might use my old function to find
> dimensions and then do whatever I want with bison.
> 
> Stratis
> 
> 
> Laurence Finston wrote:
> > 
> > 
> > On Fri, 28 Nov 2008, sgaurelius wrote:
> > 
> >> Flex scanner has previously analyzed the string and extracted the tokens.
> >> However, if I want the text that corresponds to this expression, for
> >> example
> >> the "(1+2)" and not just the tokens, what should I do ? Is there some
> >> solution ?
> > 
> > Save `yytext' somewhere "persistent".  `yytext' is available in the 
> > actions of your scanner.  You can save it in a data member of an object 
> > that you pass as a parameter to `yylex'.  If you use Flex, you can pass a 
> > parameter of a certain type (I'd have to look up what it's called) and 
> > declare an object of a type of your choice to be a data member of this 
> > object.  I use this to carry around information that needs to be available 
> > within my scanner and parser rules, and outside them.  This is a 
> > thread-safe approach.
> > 
> > Alternatively, you could pass the strings back to `yyparse' as the 
> > semantic values of the tokens, _unless_ you need the semantic values to be 
> > numeric values or something else.  This might be easier, because you 
> > wouldn't have to keep track of which string is associated with a given 
> > token.  If you chose this approach, you might have to convert strings to 
> > numbers in your parser rules, which isn't very difficult.
> > 
> > There are probably other approaches, but these are the ones that occur to 
> > me off the top of my head.  However, I can't think of any reason why I 
> > would want to keep the strings.
> > 
> > Laurence Finston
> > 
> > 
> > _______________________________________________
> > address@hidden http://lists.gnu.org/mailman/listinfo/help-bison
> > 
> > 
> 
> -- 
> View this message in context: 
> http://www.nabble.com/How-to-get-the-text-corresponding-to-a-bison-rule-tp20732674p20734369.html
> Sent from the Gnu - Bison - Help mailing list archive at Nabble.com.
> 
> 
> 
> _______________________________________________
> address@hidden http://lists.gnu.org/mailman/listinfo/help-bison
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]