Re: Query on YAPP Usage

Martin Klang <[email protected]> Wed, 22 Aug 2007 14:34:46 +0100
Newsgroups gmane.text.xml.o-xml
Message-ID <[email protected]>
Hi there,

Thanks for using YAPP, apologies that documentation and examples  
aren't quite up to scratch. If you would like to contribute e.g. with  
code examples or docs, please feel free.

Your grammar contains a construct that is left recursive, which makes  
it unparseable by recursive descent parsers - see for example http:// 
en.wikipedia.org/wiki/Left_recursion for more details.

YAPP is a recursive descent parser, hence the generated grammar  
doesn't produce a valid parser.
The solution is quite simple, YAPP comes with a stylesheet that will  
eliminate left recursion.

I managed to get your example working with the following process:

1) create YAPP BNF parser and lexer.
xalan -XSL generator.xsl -IN bnf-grammar.xml > bnf-parser.xsl
xalan -XSL tokenizer.xsl -IN bnf-grammar.xml > bnf-lexer.xsl

2) generate XML grammar from calculator BNF grammar:
xalan -XSL bnf-parser.xsl -IN calculator-grammar.bnf > calculator- 
grammar.xml

3) fix left recursion problem:
xalan -XSL eliminator.xsl -IN calculator-grammar.xml > fixed- 
calculator-grammar.xml

3) generate parser and lexer:
xalan -XSL generator.xsl -IN fixed-calculator-grammar.xml >  
calculator-parser.xsl
xalan -XSL tokenizer.xsl -IN fixed-calculator-grammar.xml >  
calculator-lexer.xsl

All files apart from calculator-grammar.bnf are supplied with YAPP, I  
created it from your example as follows:
<grammar>
   <terminal name="end">
     <end/>
   </terminal>
   <ignore char=" "/>
   <bnf>
minus ::= '-' ;
plus ::= '+' ;
number ::= [.0123456789] ;
Expression ::= AdditiveExpression end ;
AdditiveExpression ::= number | AdditiveExpression minus number |  
AdditiveExpression plus number ;
   </bnf>
</grammar>

I then called the resulting parser with this stylesheet:
<xsl:stylesheet version="1.0"
                 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:p="http://www.pingdynasty.com/namespaces/parser">
   <xsl:import href="calculator-lexer.xsl"/>
   <xsl:import href="calculator-parser.xsl"/>
   <xsl:template match="/">
     <output>
       <xsl:call-template name="p:Expression">
         <xsl:with-param name="in" select="'123 + 456 - 789'"/>
       </xsl:call-template>
     </output>
   </xsl:template>
</xsl:stylesheet>

... and I got this result:
<output>
   <term name="Expression">
     <term name="AdditiveExpression">
       <term name="number">123</term>
       <term name="AdditiveExpression-rest">
         <term name="plus">+</term>
         <term name="number">456</term>
         <term name="AdditiveExpression-rest">
           <term name="minus">-</term>
           <term name="number">789</term>
           <term name="AdditiveExpression-rest"/>
         </term>
       </term>
     </term>
     <term name="end"/>
   </term>
   <remainder/>
</output>


The construct called AdditiveExpression-rest has been created by  
YAPP, it can be ignored, or filtered out with another XSL.

I hope this helps, let me know how it goes!

/m