<!DOCTYPE book PUBLIC "-//Davenport//DTD DocBook V3.0//EN">

<book id="quickstart-guide">
  <title>
    The glrParser Quick Start Guide
  </title>
  <bookinfo>
    <author>
      <firstname>Ondrej</firstname>
      <surname>Macek</surname>
    </author>
    <legalnotice>
      <blockquote>
        <para>
          This document alike all other parts of The <classname>glrParser</classname> Project can be
	  distributed and/or modified under the terms of GNU General Public License
	  version 2 or greater.
        </para>
      </blockquote>
    </legalnotice>
    <abstract>
      <para>
        This guide is intended for programmers who start use The <classname>glrParser</classname> Template Library.
	It explains what is the library made for and then it will guide you
	step by step through the usage of the library starting with the concept fellowed
	by the analysis of two samples.
      </para>
    </abstract>
  </bookinfo>
  <chapter>
    <title>
      Introduction
    </title>
    <para>
      The goal of The <classname>glrParser</classname> Project is to create generaly usable programmers tool
      for syntactical analysis of wide ambiguous grammars which works with the GLR(0) algorithm.
      GLR is well known algorithm published by Marasu Tomita in 1985. It is based on generalization
      of the LR analysis.
    </para>
    <para>
      In the documantation I suppose knowledge of the GLR algorithm and I use the terminology
      from Tomita's book Effecient Parsing For Natural Language. Particularly I use the term "vertex"
      for vertices of the "graph structored stack" and the term "node" for nodes of the "packed shared forest".
    </para>
    <para>
      <classname>glrParser</classname> defines nor actions to make while making reductions neither method of reading terminals
      from input. <classname>glrParser</classname> defines format of files with grammar, but you can simply make the parser
      to use different format (see <classname>glrParser</classname> and <classname>glrGrammar</classname> in the reference guide).
      Parser is oriented for creating the packed shared forest, but it is not the condition.
    </para>
  </chapter>
  <chapter>
    <title>
      Concept
    </title>
    <para>
      The analyser is realised in form of template library written in C++. In its center is the <classname>glrParser</classname>
      template and the <classname>glrNode</classname> class. <classname>glrNode</classname> is the base class for classes which
      should be used to represent nodes of generated packed shared forest.
    </para>
    <para>
      Before you begin you should know that the parser internally doesn't use text representation of symbols
      that appears in the grammar but it uses the type <type>glrSymbol</type> defined in the 
      <filename>glrSymbolTable.h</filename> header. To convert values of type <type>glrSymbol</type> to C++ strings
      and backwards serves the object <structfield>symbols</structfield> of type <classname>glrSymbolTable</classname> declared
      in the <classname>glrParser</classname> template as protected.
    </para>
    <para>
      Usage of <classname>glrParser</classname> usually consists of fellowing steps:
      <orderedlist>
        <listitem>
	  <para>
	    Definition of some class derived from the <classname>glrNode</classname> class. This class will represent
	    the node of generated packed shared forest and should be
	    used as the first argument to the <classname>glrParser</classname> template. It should also have
	    some mantadory constructors which will be used by the parser when it makes reduction which leads to
	    creating new node of the pa. sh. forest. You will also almoust override the <function>addSubtree</function>
	    declared in the <classname>glrNode</classname> class as virtual. It is called when the parser makes reduction
	    which leads to adding alternative subtree to existing node of the forest.
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Definition of the class derived from the class <classname>glrParser class glrNodeType</classname> where as
	    the argument should be specified the class created in the first step.
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Definition of the class derived from the <classname>glrNode</classname> class to represent terminals in the
	    packed shared forest.
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Overriding of the <function>readToken</function> function which is called when the parser want to read
	    next terminal from input. This implies necessity of creating of some mechanism for reading terminals
	    and associating them with appropriate preterminals which appears in grammar.
	  </para>
	</listitem>
      </orderedlist>
    </para>
  </chapter>
  <chapter>
    <title>
      The basic parser
    </title>
    <para>
      This chapter analyses the simpliest parser which can be created using the <classname>glrParser</classname>
      library. The presented sample covers just second and fourth step according to the concept above. It uses
      straightly the class <classname>glrNode</classname> to represent both -- terminal and nonterminal nodes.
      Therefore no packed shared forest is created by the basic parser. The parser can be used merely to detect
      wether the input is syntactically corect according to assigned grammar. The input is syntacticaly correct
      iff the <function>glrParser::getForestRoot</function> function returns non-NULL after parsing finishes.
    </para>
    <para>
      The source code of the sample looks thus:
      <programlisting><![CDATA[
#include <sys/time.h>

#include <glr/glrParser.h>

#include <iostream>
#include <fstream>
#include <strstream>

using namespace std;
      ]]></programlisting>
    </para>
    <para>
      The common begin is fellowed by declaration of the <classname>basicParser</classname> class. The associative
      container <structfield>terminals</structfield> is used discover which preterminal symbols of the grammar are matched
      by the terminal on input. Note that the parser can handle situations when many (more tn one) preterminals
      are matched by one terminal on input.
      <programlisting><![CDATA[
class basicParser : public glrParser<glrNode> {
  private:
    map<string,vector<glrSymbol> > terminals;
    istream *input;
  protected:
    virtual void readToken();
  public:
    void readTerminals(istream &input);
    void setInput(istream *inputA);
};
      ]]></programlisting>
    </para>
    <para>
      Function <function>readTerminals</function> reads the set of terminals which will be recognized by the parser.
      It stores them to the <structfield>terminals</structfield> associative container. To every terminal is associated
      the vector of appropriate symbols (preterminals). The <structfield>symbols</structfield> field is used to
      convert preterminals represented by strings to the <type>glrSymbol</type> type velues. The input sould be organized
      into the pairs where the terminal is on the first place and appropriate preterminal is on the second place.
      All should be delimited by white space.
      <programlisting><![CDATA[
void basicParser::readTerminals(istream &input){
  string terminal,preterminal;
  while(input >> terminal >> preterminal){
    terminals[terminal].push_back(symbols.getSymbolFromString(preterminal));
  }
}
      ]]></programlisting>
    </para>
    <para>
      Function <function>setInput</function> just assignes the input to parsing.
      <programlisting><![CDATA[
void basicParser::setInput(istream *inputA){
  input=inputA;
}
      ]]></programlisting>
    </para>
    <para>
      Function <function>readToken</function> is called by the parser (during parsing) when next 
      terminal should be read from input. It creates new object of type <classname>glrNode</classname> for
      each symbol which is matched by the terminal read from input. It places the pointers to newly created
      objects to the <structfield>preterminals</structfield> container, which is declared as protected in the
      <classname>glrParser</classname> template. If the <structfield>preterminals</structfield> container
      is empty after return from this function, the parser assumes that it is on the end of input.
      <programlisting><![CDATA[
void basicParser::readToken(){
  string terminal;
  if(*input >> terminal){
    map<string,vector<glrSymbol> >::iterator preter=terminals.find(terminal);
    if(preter!=terminals.end()){
      for(vector<glrSymbol>::iterator t=preter->second.begin();
          t!=preter->second.end();++t)
        preterminals.push_back(new glrNode(*t));
    }
  }
}
      ]]></programlisting>
    </para>
    <para>
      To keep the basic parser as simple as it can be, the main function doesn't parse command line arguments
      but take the first argument as the name of the file with grammar, the second argument as the file with
      terminals and the third argument as the file with text to parse. The fourth argument is number
      which specifies how many times the input should be parsed. This I made for profiling and debugging purposes.
      <programlisting><![CDATA[
int main(int argc,char**argv){

  /*
   * The grammar initialization and the glr table computation.
   */

  basicParser parser;
  ifstream *input;
  input=new ifstream(argv[1]);
  parser.initGrammar(*input);
  delete input;
  parser.computeTable();
  input=new ifstream(argv[2]);
  parser.readTerminals(*input);
  delete input;

  /*
   * Parser can print the status to verify if grammar was succesfully
   * read and the glr table computed.
   */

  parser.printStatus(cout);

  /*
   * Running the whole parsing and the time measuring.
   */

  int times;
  {
    istrstream istr(argv[4]);
    istr >> times;
  }
  struct timeval begin,end;
  gettimeofday(&begin,NULL);
  for(int i=0;i<times;++i){
    input=new ifstream(argv[3]);
    parser.setInput(input);
    parser.parse();
    delete input;
  }
  gettimeofday(&end,NULL);

  /*
   * Parsing time printing.
   */

  cerr << "input parsed " << (int)times << " times in "
       << (end.tv_sec-begin.tv_sec)-(end.tv_usec<begin.tv_usec) << " seconds and "
       << ((end.tv_usec<begin.tv_usec)?(1000000-begin.tv_usec+end.tv_usec)
                                      :(end.tv_usec-begin.tv_usec))
       << " micoseconds" << endl;

  /*
   * Detecting if input is correct => getForestRoot() should not be null if the
   * reduction was made along the rule number 0 upon whole input.
   */

  if(parser.getForestRoot())
    cout << "input is syntacticaly correct according to this grammar" << endl;
  else
    cout << "no derivation tree found for input" << endl;

  /*
   * Dealocating of the grammar.
   */

  parser.releaseGrammar();
}
      ]]></programlisting>
    </para>
  </chapter>
  <chapter>
    <title>
      More complex parser
    </title>
    <para>
      The parser in this sample uses the <classname>glrParser</classname> library to create packed shared forest,
      from which it will be possible to elict number of trees stored as well as print the trees.
    </para>
    <simplesect>
      <title>
        The declarations of the complex parser
      </title>
      <para>
        <programlisting><![CDATA[
#include <sys/time.h>
#include <unistd.h>

#include <iostream>
#include <fstream>
#include <strstream>
#include <vector>
#include <deque>
#include <string>

#include <glr/glrParser.h>
        ]]></programlisting>
      </para>
      <para>
        Number of nodes of packed shared forest will be counted for debugging reasons.
        <programlisting><![CDATA[
int numNodes=0;
        ]]></programlisting>
      </para>
      <para>
        Class <classname>stringForest</classname> is used to generate, store and print text representation of the forest.
        Note that this representation of forest is nor packed neither shared; therefore its size can grow exponentially
        with regard to number of tokens of parsed sentence.
        <itemizedlist>
          <listitem>
	    <para>
	      Operator <function>*=</function> replaces the original forest with the carthesian product of the
	      original forest and the forest specified by the <structfield>forest</structfield> argument.
	      The forest in the <structfield>forest</structfield> argument is dealocated.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Operator <function>+=</function> with the <classname>stringForest*</classname> type argument appends
	      the forest in the <structfield>forest</structfield> argument to the end of the original forest.
	      The forest in the <structfield>forest</structfield> argument is dealocated.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Operator <function>+=</function> with the <classname>string</classname> type argument appends the
	      string in <structfield>suffix</structfield> to the end of all stored strings (trees).
	    </para>
	  </listitem>
        </itemizedlist>
        <programlisting><![CDATA[
class stringForest : public vector<string> {
  public:
    stringForest &operator *= (stringForest *forest);
    stringForest &operator += (stringForest *forest);
    stringForest &operator += (const string &suffix);
    void print(ostream &output,int numberOfTokens);
};
        ]]></programlisting>
      </para>
      <para>
        Class <classname>commonNode</classname> is the base class for the classes that represent terminals and
        nonterminals in the packed shared forest. It declares virtual functions that will be common to thous
        classes. Constructors and destructor are used to count number of nodes in the packed shared forest.
        Constructors also call appropriate constructors of the base class (this behaviour is mantadory).
        <itemizedlist>
          <listitem>
	    <para>
	      Function <function>getNumberOfSubtrees</function> serves for counting the number of subtrees
	      of the node. The behaviour of returning 1 is inherited by the class which represents terminals nodes.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Function <function>getForest</function> generates the text representation of subtrees of the node.
	    </para>
	  </listitem>
        </itemizedlist>
        <programlisting><![CDATA[
class commonNode : public glrNode {
  public:

    commonNode(const glrSymbol &symbolA) : glrNode(symbolA) { ++numNodes; }
    commonNode(const glrRule* const &ruleA) : glrNode(ruleA) { ++numNodes ;}
    commonNode(const glrRule* const &ruleA,const deque<glrNode*> &succA) : glrNode(ruleA,succA) { ++numNodes; }
    virtual ~commonNode() { --numNodes; }

    virtual unsigned long long getNumberOfSubtrees() { return 1; }
    virtual stringForest *getForest(const glrSymbolTable &symbols) { return (stringForest*)NULL; }
};
        ]]></programlisting>
      </para>
      <para>
        Class <classname>nunterminalNode</classname> is used to represent the nonterminal nodes of the packed
        shared forest. It will be passed as the first argument to the <classname>glrParser</classname> template.
        <itemizedlist>
          <listitem>
	    <para>
	      The <structfield>succ</structfield> field is used to store subtrees of the node.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The <structfield>numberOfSubtrees</structfield> field is used to store number of subtrees of the node.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The <structfield>passed</structfield> flag is used to indicate that the node was already
	      walked through by the <function>getNumberOfSubtrees</function> and the <function>getForest</function>
	      recursive functions.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The constructors are mantadory by the <classname>glrParser</classname> template as well as the behaviour
	      of calling appripriate constructor of the base class.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The <function>addSubtree</function> is overrided function which is declared in the <classname>glrNode</classname>
	      class. It is called by the parser when new subtree should by added to the node.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The <function>getForest</function> function returns the text representation of subtrees of the node.
	    </para>
	  </listitem>
        </itemizedlist>
        <programlisting><![CDATA[
class nonterminalNode : public commonNode {
  private:
    deque<deque<commonNode*> > succ;
    unsigned long long numberOfSubtrees;
    bool passed;
  public:
    nonterminalNode(const glrRule* const &ruleA);
    nonterminalNode(const glrRule* const &ruleA,const deque<glrNode*> &succA);
    virtual void addSubtree(const glrRule* const &ruleA,const deque<glrNode*> &succA);
    virtual ~nonterminalNode();
    virtual unsigned long long getNumberOfSubtrees() ;
    virtual stringForest *getForest(const glrSymbolTable &symbols) ;
};
        ]]></programlisting>
      </para>
      <para>
        Class <classname>terminalNode</classname> is used to represent terminal nodes of the packed shared forest.
        <itemizedlist>
          <listitem>
	    <para>
	      The <structfield>terminal</structfield> field is appropriate terminal.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The constructor is called by the <function>complexParser::readTerminals</function> function.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      The destructor does nothing at this time.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Function <function>getForest</function> returns the text representation of the terminal
	      (and appropriate preterminal).
	    </para>
	  </listitem>
        </itemizedlist>
        <programlisting><![CDATA[
class terminalNode : public commonNode {
  private:
    string terminal;
  public:
    terminalNode(const glrSymbol &symbolA,const string &terminalA);
    virtual ~terminalNode() {}
    virtual stringForest *getForest(const glrSymbolTable &symbols) ;
};
        ]]></programlisting>
      </para>
      <para>
        Class <classname>complexParser</classname> is the whole parser. The mechanizm of storing the
        vocabulary of terminals is the same as in the basic parser.
        <itemizedlist>
          <listitem>
	    <para>
	      The <function>readToken</function> is almost the same as in the basic parser.
	      (It is called by the parser when new terminal have to be read.)
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Functions <function>getNumberOfTrees</function> and <function>printForest</function> just calls
	      appropriate functions of the root node of generated packed shared forest (if such node exists).
	    </para>
	  </listitem>
        </itemizedlist>
        <programlisting><![CDATA[
class complexParser : public glrParser<nonterminalNode> {
  private:
    map<string,vector<glrSymbol> > terminals;
    istream *input;
  protected:
    virtual void readToken();
  public:
    void readTerminals(istream &input);
    void setInput(istream *inputA);
    unsigned long long getNumberOfTrees();
    void printForest(ostream &output);
};
        ]]></programlisting>
      </para>
    </simplesect>
    <simplesect>
      <title>
        The implementations of the complex parser
      </title>
      <para>
        Implementation of operators and <function>print</function> function of the <classname>stringForest</classname> class.
	<programlisting><![CDATA[
stringForest &stringForest::operator *= (stringForest *forest){
  stringForest::iterator i=forest->begin();
  i++;
  int len=size();
  while(i!=forest->end()){
    for(int j=0;j<len;++j){
      push_back((*this)[j]+(*i));
    }
    i++;
  }
  for(int j=0;j<len;++j)(*this)[j]+=(*forest->begin());
  delete forest;
}

stringForest &stringForest::operator += (stringForest *forest){
  insert(end(),forest->begin(),forest->end());
  delete forest;
}

stringForest &stringForest::operator += (const string &suffix){
  for(stringForest::iterator i=begin();i!=end();++i)(*i)+=suffix;
}

void stringForest::print(ostream &output,int numberOfTokens){
  for(stringForest::iterator i=begin();i!=end(); output << " 0 " << numberOfTokens << " " << (*(i++)) << endl);
}
        ]]></programlisting>
      </para>
      <para>
        Implementation of the <classname>nonterminalNode</classname> constructors. Their type is mantadory
	as well as the behaviour of calling of appropriate constructor of the base class.
      </para>
      <para>
        The first constructor is called when reduction along the epsilon rule is made.
        <programlisting><![CDATA[
nonterminalNode::nonterminalNode(const glrRule* const &ruleA) : commonNode(ruleA) { passed=false; }
        ]]></programlisting>
      </para>
      <para>
        The second constructor is called when reduction along the nonepsilon rule is made. It just adds new 
	subtree to the node.
	<programlisting><![CDATA[
nonterminalNode::nonterminalNode(const glrRule* const &ruleA,const deque<glrNode*> &succA) : commonNode(ruleA,succA) {
  passed=false;
  addSubtree(ruleA,succA);
}
        ]]></programlisting>
      </para>
      <para>
        Destructor of the <classname>nonterminalNode</classname> class. It calls the <function>release</function>
	function to all stored nodes of the forest to work the garbagge collector implemented by the <classname>
	glrGuard</classname> class (which is the base class of the <classname>glrNode</classname> class).
	It decreases stored number of pointers to the object and possibly calls its destructor. The condition
	is there because of some situations which can confuse the dealocation mechanism. This may come up
	just when using some type of cyclical grammars.
	<programlisting><![CDATA[
nonterminalNode::~nonterminalNode(){
  for(deque<deque<commonNode*> >::iterator iSucc=succ.begin();iSucc!=succ.end();++iSucc)
    for(deque<commonNode*>::iterator iNode=iSucc->begin();iNode!=iSucc->end();++iNode)
      if(*iNode!=this)(*iNode)->release();
}
        ]]></programlisting>
      </para>
      <para>
        The <function>addSubtree</function> is called by the parser when new subtree has to be added to existing 
	(this) node (the same reduction was made upon the same part of the input but different way). The
	<function>shackle</function> is called to work the garbagge collector implemented by the <classname>
	glrGuard</classname> class (which is the base class of the <classname>glrNode</classname> class.
	It increases the stored number of pointers to the object. The condition is there beacuse of
	some situations which may come up in some cyclical grammars.
	<programlisting><![CDATA[
void nonterminalNode::addSubtree(const glrRule* const &ruleA,const deque<glrNode*> &succA){
  succ.push_back((const deque<commonNode*>&)succA);
  for(deque<commonNode*>::iterator iNode=succ.back().begin();iNode!=succ.back().end();++iNode){
    if(*iNode!=this)(*iNode)->shackle();
  }
}
         ]]></programlisting>
      </para>
      <para>
        Implementation of the algorithm for counting the number of subtrees of the node. It uses the
	<structfield>passed</structfield> flag to indicate that the node was already walked through
	and the <structfield>numberOfSubtrees</structfield> to store counted number of subtrees
	of the node. This has two reasons. The first is that the time to count number of subtrees
	is polynomial even thought the number of subtrees itself can grow exponentially.
	The second is that the algorithm doesn't cycling in the case that there is a cyclus
	in the graph representing the forest. Note that this can come up just if parsing
	wickedly cyclical grammar.
        <programlisting><![CDATA[
unsigned long long nonterminalNode::getNumberOfSubtrees(){
  if(passed)return 0;
  if(!numberOfSubtrees){
    passed=true;
    for(deque<deque<commonNode*> >::iterator iSub=succ.begin();iSub!=succ.end();++iSub){
      unsigned long long one=1;
      for(deque<commonNode*>::iterator iNode=iSub->begin();iNode!=iSub->end();++iNode){
        one*=(*iNode)->getNumberOfSubtrees();
      }
      numberOfSubtrees+=one;
    }
    passed=false;
  }
  return numberOfSubtrees;
}
        ]]></programlisting>
      </para>
      <para>
        Implementation of the <function>getForest</function> function that generates the
	text representation of subtrees of the node. The function is almost same as the
	<function>getNumberOfSubtrees</function> due to redefinition of operators
	upon the <classname>stringForest</classname> class. The difference is that there
	is no mechanism to store generated text representation of subtrees. There is no lack
	of polynomial time because the size of generated structore is exponential.
	Therefore it should be used only for forests with small number of trees.
	<programlisting><![CDATA[
stringForest *nonterminalNode::getForest(const glrSymbolTable &symbols) {
  if(passed)return NULL;
  if(getType()==glrEpsilonNode){
    stringForest *all=new stringForest;
    all->push_back(string(" { ")+symbols.getStringFromSymbol(getSymbol())+" } ");
    return all;
  }else{
    passed=true;
    stringForest *all,*given;
    all=new stringForest;
    bool allSuccess=false;
    for(deque<deque<commonNode*> >::const_iterator iSucc=succ.begin();iSucc!=succ.end();++iSucc){
      bool success=false;
      stringForest *one=new stringForest;
      one->push_back(string(" { ")+symbols.getStringFromSymbol(getSymbol())+" ");
      for(deque<commonNode*>::const_iterator iNode=iSucc->begin();iNode!=iSucc->end();++iNode){
        given=(*iNode)->getForest(symbols);
        if(given!=NULL){
          (*one)*=given;
          success=true;
        }
      }
      if (success) { (*all)+=one; allSuccess=true; }
      else delete one;
    }
    if(allSuccess){
      (*all)+="} ";
    }else{
      delete all;
      all=NULL;
    }
    passed=false;
    return all;
  }
}
        ]]></programlisting>
      </para>
      <para>
        Constructor of the <classname>terminalNode</classname> class. The behaviour of calling appropriate
	constructor of the base class is mantadory.
	<programlisting><![CDATA[
terminalNode::terminalNode(const glrSymbol &symbolA,const string &terminalA) : commonNode(symbolA) {
  terminal=terminalA;
}
        ]]></programlisting>
      </para>
      <para>
        Function to return text representation of the terminal and the preterminal.
	<programlisting><![CDATA[
stringForest *terminalNode::getForest(const glrSymbolTable &symbols) {
  stringForest *ret=new stringForest;
  ret->push_back(string(" { ")+symbols.getStringFromSymbol(getSymbol())+"\\n"+terminal+" } ");
  return ret;
}
        ]]></programlisting>
      </para>
      <para>
        The <function>readToken</function>, <function>readTerminals</function> and <function>setInput</function>
	functions are almost same as in the basic parser.
	<programlisting><![CDATA[
void complexParser::readTerminals(istream &input){
  string terminal,preterminal;
  while(input >> terminal >> preterminal){
    terminals[terminal].push_back(symbols.getSymbolFromString(preterminal));
  }
}

void complexParser::readToken(){
  string terminal;
  if(*input >> terminal){
    map<string,vector<glrSymbol> >::iterator preter=terminals.find(terminal);
    if(preter!=terminals.end())
      for(vector<glrSymbol>::iterator t=preter->second.begin();t!=preter->second.end();++t)
        preterminals.push_back(new terminalNode(*t,preter->first));
  }
}

void complexParser::setInput(istream *inputA){
  input=inputA;
}
        ]]></programlisting>
      </para>
      <para>
        Implementation of the <function>getNumberOfTrees</function> and the <function>printForest</function> functions.
        <programlisting><![CDATA[
unsigned long long int complexParser::getNumberOfTrees(){
  if(!getForestRoot())return 0;
  return getForestRoot()->getNumberOfSubtrees();
}

void complexParser::printForest(ostream &output){
  if(commonNode *root=getForestRoot()){
    stringForest *forest=root->getForest(symbols);
    forest->print(output,getNumOfTokens());
    delete forest;
  }
}
	]]></programlisting>
      </para>
      <para>
        The command line help.
	<programlisting><![CDATA[
void printUsage(ostream &out){
  out << "Usage: glrparse [-g grammar] [-l table] [-f input] [-r terminals] [-t] [-s] [-p #n] [-w table_out]" << endl << endl
      << "Options/Arguments:" << endl
      << "      -g grammar      grammar file. Default file name is ,,grammar''" << endl
      << "      -l table        glr table file. If not specified, table is computed dynamicaly." << endl
      << "      -f input        file with input for parsing." << endl
      << "      -r terminals    terminals file. Default file name is ,,terminals''" << endl
      << "      -t              print text representation of forest on cout." << endl
      << "                      If not specified, only number of trees found is printed." << endl
      << "      -s              print parser status when parser is ready to parsing." << endl
      << "      -p #n           repeat parsing #n times and then print the whole parsing time." << endl
      << "      -w table_out    write glr table to file table_out." << endl << endl
      << "either -w or -f option have to be specified" << endl << endl;
}
        ]]></programlisting>
      </para>
      <para>
        The <function>main</function> consists particularly of parsing command line arguments,
	creating the parser (<classname>complexParser</classname> object and calling its functions.
	There is also the oprion for repetetive parsing of the input for profiling reasons.
	<programlisting><![CDATA[
int main(int argc,char**argv){
  string grammar="grammar",table="",terminals="terminals",input="",tableOut="";
  bool printStatus=false,printForest=false;
  int repeat=0;
  const char *optString="g:l:f:r:tw:sp:";
  int c;
  while((c=getopt(argc,argv,optString))!=-1){
    switch(c){
      case 'g': grammar=optarg; break;
      case 'l': table=optarg; break;
      case 'f': input=optarg; break;
      case 'r': terminals=optarg; break;
      case 't': printForest=true; break;
      case 'w': tableOut=optarg; break;
      case 's': printStatus=true; break;
      case 'p':
        {
        istrstream istr(optarg);
        istr >> repeat;
        break;
        }
      default: printUsage(cerr); exit(1);
    }
  }
  if((input=="")&&(tableOut=="")){
    printUsage(cerr);
    exit(2);
  }
  complexParser parser;
  istream *file;
  file=new ifstream(grammar.c_str());
  if(file->good())
    parser.initGrammar(*file);
  else{
    cerr << "can't read grammar from file \'" << grammar << "\'" << endl;
    delete file;
    exit(3);
  }
  delete file;
  if(table!=""){
    file=new ifstream(table.c_str());
    if(file->good())
      parser.readTable(*file);
    else{
      cerr << "can't read glr table from file '" << table << "' => defaulting to glr table computation" << endl;
      parser.computeTable();
    }
    delete file;
  }else{
    parser.computeTable();
  }
  file=new ifstream(terminals.c_str());
  if(file->good())
    parser.readTerminals(*file);
  else{
    cerr << "can't read terminals from file '" << terminals << "'" << endl;
    delete file;
    exit(4);
  }
  delete file;
  if(tableOut!=""){
    ofstream file(tableOut.c_str());
    if(file.good())
      parser.printTable(file);
    else{
      cerr << "can't write glr table to file '" << tableOut << "'" << endl;
    }
  }
  if(printStatus){
    parser.printStatus(cerr);
    cerr << endl;
  }
  if(input!=""){
    struct timeval begin,end;
    gettimeofday(&begin,NULL);
    for(int i=0;(i<repeat)||((repeat==0)&&(i<1));++i){
      file=new ifstream(input.c_str());
      if(file->good()){
        parser.setInput(file);
        parser.parse();
      }else{
        cerr << "can't read input from file '" << input << "'" << endl;
        delete file;
        exit(5);
      }
      delete file;
    }
    gettimeofday(&end,NULL);
    if(printForest)
      parser.printForest(cout);
    else
      cout << "number of trees in resultant forest is " << parser.getNumberOfTrees() << endl;
    cerr << "number of nodes in packed shared forest is " << numNodes << endl;
    if(repeat){
      cerr << "input parsed " << (int)repeat << " times in "
           << (end.tv_sec-begin.tv_sec)-(end.tv_usec<begin.tv_usec) << " seconds and "
           << ((end.tv_usec<begin.tv_usec)?(1000000-begin.tv_usec+end.tv_usec):(end.tv_usec-begin.tv_usec))
           << " micoseconds" << endl;
    }
  }
  parser.releaseGrammar();
}
	]]></programlisting>
      </para>
      <para>
        The source code of this example is located in the samples directory.
      </para>
    </simplesect>
  </chapter>
</book>
