| LLOOP Index | GSP Language | GSP Library | Framework Classes | Component Classes |
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 |