LLOOP Index | GSP Language | GSP Library | Framework Classes | Component Classes

gspc_rc.gsp

This is the verbatim text of the file "gspc_rc.gsp" part of the LLOOP package. The copyright remains with Michel MEHL. All rights reserved.



import uint;
import word;

symbol SReductionCodeRef extends class ReductionCodeRef()
  test 
  {{
    "$1"               : pass {$1}
    "#1"               : pass {#1}
    "&6"               : pass {&6}
    "$4(#)"            : pass {$4(#)}            {$4.getNbComponents()}
    "$1(1, #)"         : pass {$1(1, #)}         {$1.operator()(1,(unsigned long)(1)).getNbComponents()}
    "$1(i,j,40,50, #)" : pass {$1(i,j,40,50, #)} {$1.operator()(4,(unsigned long)(i),(unsigned long)(j),(unsigned long)(40),(unsigned long)(50)).getNbComponents()}
    "$1(0)"            : pass {$1(0)}            {$1.operator()(1,(unsigned long)(0))}
    "$1(0,50,40,50)"   : pass {$1(0,50,40,50)}   {$1.operator()(4,(unsigned long)(0),(unsigned long)(50),(unsigned long)(40),(unsigned long)(50))}
    "#1(#)"            : fail {#1(#)}            {#1(#)}
    "#1(1, 2, #)"      : fail {#1(1, 2, #)}      {#1(1, 2, #)}
    "#1(2, #)"         : fail {#1(2, #)}         {#1(2, #)}
    }} ;

string SSymType;
string SSymRef;

SReductionCodeRef ::= SSymType  uint [ '(' [ SSymRef { ',' SSymRef } ] ')' ]
{{
  setEmpty();

  /* Get the name of the symbol for which to parse a reference */

  universal::String sSymName = getRedSymbolName();  // Don't confuse with getSymbolName() generated for symbol SReductionCodeRef !!

  /* Determine whether a counter value is requested */

  bool bCounterRequested = false;
  if (&3)
    {
      if (&4)
	{
	  if ($4(#) > 0)
	    {
	      bCounterRequested = ($4.lastComponent()->toString() == "#");
	    }
	}
      else
	{
	  bCounterRequested = ($3.toString() == "#");
	}
    }

  /* For constant, no counter can be got anymore, except
   * if the constant is part of a choice.
   */

  if (bCounterRequested && (($1 == "#") && !m_bIsChoice))
  { 
    strstream err;
    Symbol::expand(err); err << ends;
    parser.hideLineNo();
    fatal("'%s': sorry, this writing is not supported for simple constants\n", err.str());
  }

  /* Translate the parsed reference 
   * m_bIsConstChoice and m_bIsSymbolChoice can never both be set to 0.
   */
	
  if (($1 != "#") || m_bIsChoice)
    {
      unsigned long uNb = 0;
      if (&4)
	{
	  uNb = $4(#);
	  if (bCounterRequested) uNb--;
	}
      
      append($1.str());
      append($2.toString());
      if ( &3 && !(bCounterRequested && !&4))
	{
	  if ($1 == "$")
	    append(".");
	  else
	    append("->");

	  if (!sSymName.empty())
	    {
	      append(sSymName);
	      append("Composite::");
	    }

	  if ($1 == "$")
	    append("operator()");
	  else
	    append("ptr");

	  append("(");
	  append(universal::String(1 + uNb));
	  append(",");
	  append("(unsigned long)(");
	  append($3.toString());	    
	  append(")");

	    for (unsigned long i = 0; i < uNb ; i++)
	      {
		append(",");
		append("(unsigned long)(");
		append($4(i).toString());
		append(")");
	      }

	  append(")"); 

	}



      /* If this is a choice symbol and no counter is request,
       * there are specific stuff to do:
       * - For non-terminal choices, a reference to the actual parsed 
       *   right symbol must be provided, not the one to the choice symbol.
       * - For constant choices, the value of the actual parsed constant
       *   string must be provided, not the one to the choice symbol.
       */

      if (m_bIsChoice && !bCounterRequested)
	{
	  universal::String sChoiceVal = *this;
	  if ($1 != "#") // Symbol choice
	    {
	      if ($1 == "$")
		sChoiceVal = sChoiceVal + ".getRightByIndex(0)";
	      else
		sChoiceVal = "("+sChoiceVal+" ? &"+ sChoiceVal + "->getRightByIndex(0) : NULL)";
	    }
	  else // Constant choice
	    {
	      sChoiceVal = "("+sChoiceVal+" ? "+sChoiceVal+"->"+m_sFullQualifiedBaseSymbolName+"::expand().str() : \"\")";
	    }
	  set(sChoiceVal);
	}



      if (bCounterRequested)
	{
	  if ($1 == "$")
	    append(".");
	  else
	    append("->");

	  if (!sSymName.empty())
	    {
	      append(sSymName);
	      append("Composite::");
	    }

	  append("getNbComponents()");
	}
    }
  else
  {
      if (!bCounterRequested) 
	{
	  /* For iterative constants, we always return the constant
	   * regardless of the index.
	   * TODO: Not critical, as improvement later.
	   */

	  append($1.str());
	  append($2.toString());
	}
      else
	{
	  /* NOTE:
	   * THIS CODE IS NOT VALID ANYMORE. 
	   */

	  unsigned long uNb = 0;
	  if (&4)
	    {
	      uNb = $4.getNbComponents(); // The suitable method can also be directly called
	      if (bCounterRequested) uNb--;
	    }

	  if ( (&3) && !(bCounterRequested && !&4))
	    {
	      append("m_iterCounter.valueAt");
	      append("(");
	      append(universal::String(1 + uNb));
	      append(",");
	      append($3.toString());	    
	      for (unsigned long i = 0; i < uNb; i++)
		{
		  append(",");
		  append($4(i).toString());
		}
	      append(")");
	    }
	  else
	    {
	      append("m_iterCounter.value()");
	    }
	}
    }
}}
expand
{{
  os << *this;
}}

SSymType ::= '$' {{ set(#1); }}
|'#' {{ set(#1); }}
|'&' {{ set(#1); }}

SSymRef ::= word {{ set($1.str()); }}
| uint {{ set($1.toString()); }}
| '#' {{ set(#1); }}

Null ::= {{ }}

This file is part of the LLOOP Reversible Object-Oriented Parser Generator. Copyright (c) 2005-2006 Michel MEHL, France. All rights reserved. LLOOP is distributed by the company ERSA SaRL.


Copyright (c) 2005-2006 Michel MEHL, Haguenau, France
LLOOP version 1.1