gsp__Symbol.h

This is the verbatim text of the file gsp__Symbol.h part of the LLOOP package. Copyright (C) 2005-2006 ERSA. All rights reserved.



/* ###############################################################################
 
 Copyright (c) 2006 Michel MEHL, France. All rights reserved.


 Project	: gsp
 Filename	: /home/mehl/makedoc/examples/ini_parser/src/include/gsp__Symbol.h
 Author		: Michel MEHL, France
 Description	: Parse code for symbol 'Symbol'
 GSPC Version	: 1.1
 Note		: Generated File. Do not modify.


 ############################################################################### */


#ifndef __GSP__SYMBOL_H__
#define __GSP__SYMBOL_H__

#include 
#include "universal.h"

#ifdef getchar
#undef getchar
#endif

// --- Windows specific stuff --------------------
#ifndef LLOOP_DLL
#ifdef WIN32
#ifdef LLOOP_EXPORT
#define LLOOP_DLL __declspec(dllexport)
#else
#define LLOOP_DLL __declspec(dllimport)
#endif
#else
#define LLOOP_DLL
#endif
#endif
// -----------------------------------------------

namespace universal {
  class String;
}

namespace gsp {

// Forward Declarations
class Visitor;
class LLParser;
class Symbol;
class SymbolInfoCursor;
class SymbolCounter;

/**
 *secondary:
 *
 * This class provides information about a symbol in a rule. For example,
 * it tells whether the symbol is a constant, a token or a non-terminal.
 *
 * Instances of this class can be obtained using a 
 * SymbolInfoCursor object.
 *
 * Users can't construct by themselves SymbolInfo objects, but have to get 
 * them using SymbolInfoCursor objects.
 *
 */

class LLOOP_DLL SymbolInfo
{
  friend class Symbol;
  friend class SymbolInfoCursor;

public:

  static const unsigned long TOKEN_TYPE_MASK;
  static const unsigned long CONSTANT_TYPE_MASK;
  static const unsigned long NON_TERMINAL_TYPE_MASK;
  static const unsigned long EXTERNAL_SYMBOL_TYPE_MASK;

  static const unsigned long INVALID_SYMBOL_DESCRIPTION;

private:
  
  bool m_bIsValid;
  unsigned long m_uSymbolDescription;
  const LLParser& m_parser;
  SymbolInfo *m_pNext;

public:

  SymbolInfo(const SymbolInfo& si);
  virtual ~SymbolInfo();

  bool isNonTerminal() const;
  bool isTerminal() const;
  bool isToken() const;
  bool isConstant() const;
  bool isExternalSymbol() const;
  bool isValid() const;
  const char *representation() const;

protected:

  SymbolInfo& operator=(const SymbolInfo& si);

private:

  SymbolInfo(const LLParser& parser);
  SymbolInfo(unsigned long uSymbolDescription, const LLParser& parser);

  unsigned long id() const;

  bool getNext(SymbolInfo& si);
  void setNext(const SymbolInfo& symbolInfo);
}; 


/**
 *secondary:
 *
 * This class allows to navigate backwards or forwards through the symbols
 * of a rule in order to get information about them.
 *
 * Information about symbols are contained within SymbolInfo objects. 
 * 
 * An example of use is given in the implementation of the 
 * getPreviousSymbolInfo() method of base class Symbol: 
 *
 * eg:
 SymbolInfo Symbol::getPreviousSymbolInfo(const LLParser& parser) const
 {
   SymbolInfoCursor infoCursor(parent(), parser);
   infoCursor.prev();
   return infoCursor.getInfo();
 }
 */

class LLOOP_DLL SymbolInfoCursor
{
  friend class Symbol;

private:

  const unsigned long* m_uSymbolDescs;
  const Symbol& m_nonTerminal;
  const LLParser& m_parser;
  long m_lRuleRank;
  long m_lCurrentSymbolRank;
  unsigned long m_uNbRules;
  unsigned long m_uNbSymbolsInRule;

public:

  SymbolInfoCursor(const Symbol& nonTerminal, const LLParser& parser);
  virtual ~SymbolInfoCursor();
  bool next();
  bool prev();
  bool jump(long lOffset);
  SymbolInfo getInfo() const;

private:

  SymbolInfoCursor(const Symbol& nonTerminal, const LLParser& parser, const unsigned long* uSymbolDescs);

};


/**
 *secondary:
 *
 * Defines a symbol counter composite for recursively counting 
 * (possibly nested) repetitive symbol sequences 
 */

class LLOOP_DLL SymbolCounterComposite
{
protected:

  unsigned long m_uNbComponents;    // Number of elements  
  SymbolCounter **m_apComponents;   // Array of Component pointers	
  unsigned long m_uCapacity;        // Current capacity

public:

  SymbolCounterComposite();
  virtual ~SymbolCounterComposite();

  unsigned long getNbComponents() const;
  void addComponent(SymbolCounter* pComponent);
  SymbolCounter* getComponent(unsigned long uIndex);
  const SymbolCounter* getConstComponentAt(unsigned long uIndex) const;
  void destroyAllComponents();

protected:

  void ensureComponentCapacity(unsigned long uMinCapacity);
  SymbolCounter* getComponentAt(unsigned long uIterLevel, va_list arg);
};

/**
 *secondary:
 *
 * Defines a counter for recursively counting 
 * (possibly nested) repetitive symbol sequences 
 */

class LLOOP_DLL SymbolCounter : public SymbolCounterComposite
{
private:

  unsigned long m_uCounter;

public:

  SymbolCounter();
  ~SymbolCounter();
  universal::String getSymbolCounterName() const;

  unsigned long value() const;
  unsigned long valueAt(Symbol* pSymbol, unsigned long uIterLevel, ...);
  void incr();
  void reset();
};


/**
 * Base Class for all Symbol Factories.
 */

class LLOOP_DLL SymbolFactory
{
protected:

  SymbolFactory();
public:  

  virtual ~SymbolFactory();
} ;

/**
 * This is the base class from which derive all generated non-terminal and
 * token symbol classes.
 */

class LLOOP_DLL Symbol
{
  friend class SymbolInfoCursor;
  friend class LLParser;
  friend class ExpanderVisitor;
  friend class BacktracerVisitor;

private:

  static const unsigned long NB_FIRSTS;
  static const unsigned long FIRSTS[1];

private:
    
  /// Tells whether the symbol was parsed 
  bool m_bIsParsed;					       

  /// Tells whether a failure encountered while parsing the symbol as a root symbol
  bool m_bFailure;					       

  /// Tells whether the whitespace shall be stored or not during parsing
  bool m_bStoreWs;

  /// Tells whether whitespace eating shall be disabled. Whitespace chars
  /// become normal chars that must be parsed by any rule
  bool m_bDisableWsEating;

protected:

  /// Start Line No of this symbol before first whitespace eating
  unsigned int m_uStartLineNo;

  /// Start Line No after leading whitespaces eating
  unsigned int m_uLineNo;

  /// Tells whether leading whitespace were already eaten
  bool m_bLeadingWhitespacesEaten;

  /* The rank of the rule in the grammar which was reduced during the parsing 
   * If < 0 it means no rule was reduced (parse failure) or the symbol
   * wasn't parsed yet.
   */
  long m_lReducedRuleRank;					       

  /* The rank of the rule currently being parsed
   * If < 0 it means no rule is currently being parsed.
   */
  long m_lCurrentRuleRank;					       

  /* The rank of the symbol currently being parsed in the current rule
   * If < 0 it means no rule is currently being parsed.
   */
  long m_lCurrentSymbolRank;					       

  /// Current line count before eating whitespaces of next symbol to parse in
  /// rule
  unsigned int m_uCurrentLineCount;

  /// Line Count
  unsigned int m_uLineCount;

  /// Position of the start char in the stream before leading whitespace eating
  std::streampos m_startOffset; 

  /// Position of the end char in the stream before any trailing whitespace eating
  std::streampos m_endOffset; 

  /// Position of the start char in the stream after leading whitespace eating
  std::streampos m_offset; 

  /// Current offset of the next symbol in the current parsed ruled
  std::streampos m_currentOffset;

private:

  /// The first non-whitespace char starting the symbol
  char m_peekc;

protected:

  /// A pointer to the stream from which to read the chars
  std::istream* m_pis;
  /// A pointer to the parser invoking the symbol parsing.
  LLParser* m_pParser;

  Symbol* m_pParentSymbol;	      

  /* This is useful for the expand() functions for keeping trace
   * of the whitespaces read and render some when symbols are expanded.
   * Actually points to data of the derived classes.
   * 
   * For each symbol of the rule parsed (either constant, token
   * or non-terminal), store the whitespaces read before.
   * Coding: 00: space, 01: new line, 10: tab
   */

  unsigned char (*m_pcWsFlag)[20]; // => DerivedClass::m_cWsFlag
  unsigned short* m_puNbWs;   // => DerivedClass::m_uNbWs

  /* Composite counter for iterative symbols. The counter of the first level
   * is for the iteration of the first level. Sub counters are for iterations 
   * contained within the upper iteration and so forth.
   */

  SymbolCounter m_iterCounter;

public:
  
  Symbol();
  virtual ~Symbol();

public:
    
  /* End-user parse and expand interface */
  virtual bool parse(std::istream& is, std::ostream& os, Symbol* pParent = NULL, bool bExpectEOF = false, bool bDeactivatePreprocessing = false) = 0;
  virtual bool parse(std::istream& is, Symbol* pParent = NULL, bool bExpectEOF = false, bool bDeactivatePreprocessing = false) = 0;    
  virtual bool expand(std::ostream& os, bool bRestoreWS = true);
  virtual bool backtrace(std::ostream& os) = 0;    
  bool visit(gsp::Visitor& visitor);    
  virtual bool visit(gsp::Visitor& visitor, Symbol*& pReturnSymbol);
  virtual bool test(std::ostream& os, bool bVerbose = false) = 0;

  universal::String expand(bool bTrimFirstWhitespaces = true, bool bRestoreWS = true);    

  void outputReducedRule(std::ostream& os);

  virtual bool isToken() const = 0;
  virtual bool isNonTerminal() const = 0;

  bool fail() const;
  /*inline*/ bool parsed() const; // { return m_bIsParsed; }
  bool hasParent() const;
  Symbol& parent();    
  const Symbol& parent() const;    
  Symbol& root();
  void setParent(Symbol *pParent);    
  Symbol* getParent();  

  LLParser& parser();

  unsigned int getLineNo() const;
  unsigned int getStartLineNo() const;
  unsigned int getLineCount() const;
  void setStartLineNo(unsigned int uLineNo);
  void setLineCount(unsigned int uLineCount);
  unsigned int getCurrentLineNo() const;

  std::streampos getStartOffset() const;
  std::streampos getEndOffset() const;
  std::streampos getOffset() const;
  std::streampos getCurrentOffset() const;

  long getReducedRuleRank() const;
  long ruleid() const;
  virtual unsigned long getNbRules() const;
  virtual unsigned long getNbSymbolsInRule(long lRuleRank) const;

  virtual universal::String getSymbolName() const = 0;
  virtual SymbolInfoCursor getFirstsInfoCursor(LLParser& parser);
  virtual Symbol& getRightByIndex(unsigned long uIndex);

  void warning(std::ostream& os, unsigned long uErrorLineNo, const char* pszFormattedMsg, ...);
  void error(std::ostream& os, unsigned long uErrorLineNo, const char* pszFormattedMsg, ...);
  void error(std::streampos errorOffset, unsigned int uErrorLineNo);
  void fatal(const char* pszFormattedMsg, ...);

  virtual void reset();

  void cancelWhitespaceEating();
  void disableWhitespaceEating(bool bYes = true);
  bool isWhitespaceEatingDisabled() const;
  void inhibitStoreWs(bool bYes);

protected:

  virtual bool parseSymbol(LLParser& parser, Symbol*& rpReturnSymbol, Symbol* pParent = NULL) = 0;

  bool test(std::ostream& os,
	    unsigned long uNbTestCases,
	    universal::String* pasTestCaseNames,
	    universal::String* pasTestCaseInputs,
	    universal::String* pasTestCaseOutputs,
	    bool* pabResults,	    
	    bool bDeactivatePreprocessing,
	    bool bVerbose
	    );

  void init(LLParser& parser, Symbol* pParent, long lInitialRuleRank = -1);

  void accept();
  void reject();

  void fail(bool bFail);

  void eatTrailingWhiteSpaces();
  void eatWhiteSpaces();

  /*inline*/ char peekchar() const;
  /*inline*/ char readchar();
  /*inline*/ bool strincmpread(register const char* pszString, register unsigned int len);
  /*inline*/ bool strncmpread(register const char* pszString, register unsigned int len);

  void restore_ws(unsigned long uSymbolRank, std::ostream& os) const;

  /*inline*/ void setParsed();

  long getCurrentSymbolRank() const;
  long getCurrentRuleRank() const;
  void setReducedRuleRank(long lRuleRank); 

  virtual unsigned long getSymbolDescription(long lRuleRank, long lSymbolRank) const;
  virtual const unsigned long *getFirstsDescriptions() const;
  SymbolInfo getPreviousSymbolInfo(const LLParser& parser) const;
  SymbolInfo getNextSymbolInfo(const LLParser& parser) const;

  //bool mismatch(unsigned int uMismatchConstantIndex);
  void incrementLineCount(unsigned long uAmount = 1);

  void message(std::ostream& os, unsigned long uErrorLineNo, const universal::String& c_sPrefix, const char* pszFormattedMsg, va_list arg);

private:

  /* For the expand() method. Keep a trace of the space, tab
   * and new line chars read while eating white spaces.
   */
  void store_ws(register unsigned char uWSType);

};
}

#endif