[antlr-interest] Re: Using multiple parsers -- newbie question

biz_morland biz_morland at yahoo.com
Thu Jun 12 08:43:41 PDT 2003


Hi all,

The parser I'm developing is part of a calculator program that 
analyzes text like: 2+3^3 and contains rules that determine the order 
in which an expression is parsed --> (2+3)^3 or 2+(3^3) .

I had to create two different parsers because the rules may differ 
slightly depending on the "mode" the calculator may be in. I 
emphasize "slightly" because both parsers are 95% the same, they 
differ in just a single rule.

I noticed that no matter which parser was called by the "if" 
statement in my Java program (that is, no matter which mode my 
calculator was in), the above expression would always be parsed just 
one way regardless of mode. I had each parser in its own grammar 
file. It seemed that the parser that was preferred by the program 
only depended on which grammar file I _last_ saved/compiled. Having 
an "if" statement in the Java program seemed to make no difference.

Out of desperation I followed the "bad" way, which seems like a blunt 
way of fixing the problem. But it worked so I can't complain. However 
the second way seems interesting, if I have time at the end of this 
project I will try to implement it. I'll probably have to do some 
extra reading about the commands you mentioned. But at least it now 
seems possible to implement 2 or more parsers.

Thanks!
Greg

--- In antlr-interest at yahoogroups.com, "antlrlist" <antlrlist at y...> 
wrote:
> 
> Hello Greg,
> 
> You didn't mention the difference between ExpressionParser_1 and 
> ExpressionParser_2 nor how did you detected that "both analizers 
> where the same".
> 
> However I see where your problem might be: you might be having 
> problems with token vocabularies if ExpressionParser_1 or 
> ExpressionParser_2 define tokens in the token section or if they 
have 
> unnamed tokens (they have strings in the rules, like 
> while: "while" ... ;).
> 
> There are two ways of solving this: a bad one and a good one.
> 
> The bad one consists in renaming your lexers and treeparsers, so 
> you'd get
>  - "expression_1.g" containing: ExpressionParser_1, 
> ExpressionLexer_1, and  ExpressionTreeWalker_1.
>  - "expression_2.g" contains: ExpressionParser_2, ExpressionLexer_2 
> and ExpressionTreeWalker_2.
> 
> This solution won't probably match your needs, so you'll have to 
> implement the "good one".
> <p>
> The good one consists on defining each analizer in one separated 
> file, and using grammar inheritance in the parsers. So you'd get:
>  - "expressionLexer.g" containing ExpressionLexer
>  - "expressionParser1.g" containing ExpressionParser1
>  - "expressionParser2.g" containing ExpressionParser2
>  - "expressionTreeParser.g" containing ExpressionTreeParser
> <p>
> When you write a set of analyzers in the same file, ANTLR deals 
with 
> vocabulary sharing authomatically. If you write them in separate 
> files, you'll have to share vocabularies manually (see "Token 
> vocabularies" on antlr docs).
> <p>
> In order to do this, you must:
>  - Copy/paste each analizer's definition in each grammar file.
>  - The lexer should need to export its vocabulary with the 
> exportVocab option. Give the vocab a name like "lexer" 
> (exportVocab=lexer;).
>  - In ExpressionParser1 you shoud importVocab the Lexer's 
vocabulary 
> (importVocab=lexer;)and exportVocab the new vocabulary 
> (exportVocab=parser1;).
>  - ExpressionParser2 should be defined as a derived grammar of 
> ExpressionParser1. This is, instead of being "class 
ExpressionParser2 
> extends Parser" it will be declared like "class ExpressionParser2 
> extends ExpressionParser1". You'll also have to compile 
> expressionParser2.g with the command line "java antlr.Tool -glib 
> expressionParser1.g expressionParser2.g" (see "grammar inheritance" 
> on the docs). Grammar inheritance allows you to "import" the rules 
of 
> ExpParser1 in ExpParser2, so you only have to write the ones that 
> change.
>  - ExpressionParser2 should import the vocab of *ExpressionParser1* 
> (importVocab=parser1;) and export its own vocab 
exportVocab=parser2;).
>  - ExpressionTreeParser should import ExpressionParser2's vocab 
> (importVocab=parser2).
> 
> Tell me if this helps you
> 
> Enrique
> 
> --- In antlr-interest at yahoogroups.com, mzukowski at y... wrote:
> > I'd say try to step through it with a debugger.  I don't see any 
> obvious
> > clues here.
> > 
> > Monty
> > 
> > -----Original Message-----
> > From: biz_morland [mailto:biz_morland at y...] 
> > Sent: Wednesday, June 11, 2003 2:46 PM
> > To: antlr-interest at yahoogroups.com
> > Subject: [antlr-interest] Using multiple parsers -- newbie 
question
> > 
> > 
> > Hi,
> > 
> > I've written a Java program that uses an ExpressionParser, 
> > ExpressionLexer, and ExpressionTreeWalker. I've put these three 
> > classes in a separate grammar file called expression.g and 
> compiling 
> > and running these class doesn't produce any problems.
> > 
> > Now I've discovered an extra requirement which basically means I 
> have 
> > to create 2 parsers, each only slightly different in the way they 
> > parse some text. 
> > 
> > So now I have to write two separate classes: ExpressionParser_1 
and 
> > ExpressionParser_2. (The other classes, ExpressionLexer and 
> > ExpressionTreeWalker, should stay exactly the same.)
> > 
> > My question is, how does one implement two different parsers?
> > 
> > At first I thought, this is easy, I just have to create 2 
different 
> > parser classes, each with a different name. Maybe even create 2 
> > different grammar files to hold each new parser (since I 
discovered 
> a 
> > single grammar file cannot hold more than one parser class). 
> > 
> > So now:
> > 
> > "expression_1.g" contains: ExpressionParser_1, ExpressionLexer, 
> > ExpressionTreeWalker.
> > "expression_2.g" contains: ExpressionParser_2, ExpressionLexer, 
> > ExpressionTreeWalker.
> > 
> > And I just compile each grammar file before running my java 
> program, 
> > which seems to generate each of the classes named above.
> > 
> > In the java program I have an "if" statement that switches 
between 
> > parsers, calling either ExpressionParser_1 or ExpressionParser_2.
> > 
> > But as usual things aren't as easy as they seem, and my program 
> > refuses to differentiate between one or the other parser. Which 
> > parser class actually is used, depends only on which grammar file 
I 
> > saved last!
> > 
> > Assuming nothing's wrong with the java program itself (and with 
the 
> > if conditional that should call the appropriate parser class), 
> would 
> > anyone know why this isn't working? Or maybe even suggest a way 
to 
> > switch between 2 parsers in the same program?
> > 
> > Many thanks,
> > Greg
> > 
> > 
> > 
> > 
> > 
> > 
> >  
> > 
> > Your use of Yahoo! Groups is subject to 
> http://docs.yahoo.com/info/terms/


 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 




More information about the antlr-interest mailing list