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