root/branches/compiler/cSharp/ooasCompiler/src/parser/ooaParser.cs
3 | krennw | /**
|
|
*
|
|||
* OOAS Compiler (Deprecated)
|
|||
*
|
|||
* Copyright 2015, Institute for Software Technology, Graz University of
|
|||
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
|
|||
* of Technology. All rights reserved.
|
|||
*
|
|||
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
|||
*
|
|||
* Please notice that this version of the OOAS compiler is considered de-
|
|||
* precated. Only the Java version is maintained.
|
|||
*
|
|||
* Contributors:
|
|||
* Willibald Krenn (TU Graz/AIT)
|
|||
* Stefan Tiran (TU Graz/AIT)
|
|||
*/
|
|||
using System;
|
|||
using Antlr.Runtime;
|
|||
using System.Text;
|
|||
using System.Collections.Generic;
|
|||
using System.Text.RegularExpressions;
|
|||
namespace TUG.Mogentes
|
|||
{
|
|||
public class CompilerMessage
|
|||
{
|
|||
private string m_file;
|
|||
private int m_line;
|
|||
private int m_column;
|
|||
private string m_message;
|
|||
public CompilerMessage(string aFile, int aLine, int aColumn, string aMessage)
|
|||
{
|
|||
m_file = aFile;
|
|||
m_line = aLine;
|
|||
m_column = aColumn;
|
|||
m_message = aMessage;
|
|||
}
|
|||
public CompilerMessage(string aFile, IToken aSymbol, string aMessage)
|
|||
{
|
|||
m_file = aFile;
|
|||
m_line = aSymbol.Line;
|
|||
m_column = aSymbol.CharPositionInLine;
|
|||
m_message = aMessage;
|
|||
}
|
|||
public string file { get { return m_file; } }
|
|||
public int line { get { return m_line; } }
|
|||
public int column { get { return m_column; } }
|
|||
public string message { get { return m_message; } }
|
|||
}
|
|||
public class ParserError : CompilerMessage
|
|||
{
|
|||
public ParserError(string aFile, int aLine, int aColumn, string aMessage)
|
|||
: base(aFile, aLine, aColumn, aMessage)
|
|||
{ }
|
|||
public ParserError(string aFile, IToken aSymbol, string aMessage)
|
|||
: base(aFile, aSymbol, aMessage)
|
|||
{ }
|
|||
}
|
|||
public class ParserWarning : CompilerMessage
|
|||
{
|
|||
public ParserWarning(string aFile, int aLine, int aColumn, string aMessage)
|
|||
: base(aFile, aLine, aColumn, aMessage)
|
|||
{ }
|
|||
public ParserWarning(string aFile, IToken aSymbol, string aMessage)
|
|||
: base(aFile, aSymbol, aMessage)
|
|||
{ }
|
|||
}
|
|||
public class ParserMessage : CompilerMessage
|
|||
{
|
|||
public ParserMessage(string aFile, int aLine, int aColumn, string aMessage)
|
|||
: base(aFile, aLine, aColumn, aMessage)
|
|||
{ }
|
|||
public ParserMessage(string aFile, IToken aSymbol, string aMessage)
|
|||
: base(aFile, aSymbol, aMessage)
|
|||
{ }
|
|||
}
|
|||
public class ParserState
|
|||
{
|
|||
public ooaParser parser;
|
|||
public ooaLexer lexer;
|
|||
public string filename;
|
|||
public string namesTypePrefix = String.Empty;
|
|||
public bool parsingAttributes;
|
|||
public MainModule ooaSystem;
|
|||
public IScope currentScope;
|
|||
public List<ParserError> listOfParserErrors;
|
|||
public List<ParserWarning> listOfParserWarnings;
|
|||
public List<ParserMessage> listOfParserMessages;
|
|||
public List<OpaqueType> typesToFixUp;
|
|||
public ParserState(Program.Options options)
|
|||
{
|
|||
listOfParserErrors = new List<ParserError>();
|
|||
listOfParserWarnings = new List<ParserWarning>();
|
|||
listOfParserMessages = new List<ParserMessage>();
|
|||
typesToFixUp = new List<OpaqueType>();
|
|||
this.filename = options.fileToParse;
|
|||
this.namesTypePrefix = options.namedTypePrefix;
|
|||
ICharStream input = new ANTLRFileStream(filename, Encoding.ASCII);
|
|||
lexer = new ooaLexer(input);
|
|||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
|||
parser = new ooaParser(tokens);
|
|||
parser.pState = this;
|
|||
}
|
|||
public void AddErrorMessage(ParserError parserError)
|
|||
{
|
|||
listOfParserErrors.Add(parserError);
|
|||
}
|
|||
public void AddWarningMessage(ParserWarning parserWarning)
|
|||
{
|
|||
listOfParserWarnings.Add(parserWarning);
|
|||
}
|
|||
public void AddMessage(ParserMessage aMessage)
|
|||
{
|
|||
listOfParserMessages.Add(aMessage);
|
|||
}
|
|||
public Identifier Lookup(string symbolName, IScope resolveStack)
|
|||
{
|
|||
string lkupname = symbolName;
|
|||
do
|
|||
{
|
|||
Identifier result = resolveStack.ResolveIdentifier(lkupname);
|
|||
if (result != null)
|
|||
return result;
|
|||
resolveStack = resolveStack.GetParentScope();
|
|||
} while (resolveStack != null);
|
|||
return null;
|
|||
}
|
|||
public Identifier Lookup(string symbolName)
|
|||
{
|
|||
return Lookup(symbolName, currentScope);
|
|||
}
|
|||
public Identifier Lookup(IToken symbolName)
|
|||
{
|
|||
if (symbolName != null)
|
|||
return Lookup(symbolName.Text);
|
|||
else
|
|||
return null;
|
|||
}
|
|||
public void PushResolveStack(IScope newScope)
|
|||
{
|
|||
// some sanity check.
|
|||
if (newScope is MethodIdentifier)
|
|||
System.Diagnostics.Debug.Assert(currentScope is OoActionSystemType);
|
|||
newScope.SetParentScope(currentScope);
|
|||
currentScope = newScope;
|
|||
}
|
|||
public void PopResolveStack()
|
|||
{
|
|||
currentScope = currentScope.GetParentScope();
|
|||
}
|
|||
}
|
|||
public partial class ooaParser : Parser
|
|||
{
|
|||
public ParserState pState { get; set; }
|
|||
public bool IsRightToLeft(ExpressionKind type)
|
|||
{
|
|||
return type == ExpressionKind.implies; // implication has right grouping
|
|||
}
|
|||
public int GetOperatorPrecedence(ExpressionKind type)
|
|||
{
|
|||
switch (type)
|
|||
{
|
|||
/*Family of Evaluators*/
|
|||
case ExpressionKind.abs: // T_ABS:
|
|||
case ExpressionKind.card: // T_CARD:
|
|||
case ExpressionKind.dom: // T_DOM:
|
|||
case ExpressionKind.range: // T_RNG:
|
|||
case ExpressionKind.merge: // T_MERGE:
|
|||
case ExpressionKind.len: // T_LEN:
|
|||
case ExpressionKind.elems: // T_ELEMS:
|
|||
case ExpressionKind.head: // T_HEAD:
|
|||
case ExpressionKind.tail: // T_TAIL:
|
|||
case ExpressionKind.conc: // T_CONC:
|
|||
case ExpressionKind.inds: // T_INDS:
|
|||
case ExpressionKind.dinter: // T_DINTER:
|
|||
case ExpressionKind.dunion: // T_DUNION:
|
|||
return 1;
|
|||
case ExpressionKind.domresby: // T_DOMRESBY:
|
|||
case ExpressionKind.domresto: // T_DOMRESTO:
|
|||
case ExpressionKind.rngresby: // T_RNGRESBY:
|
|||
case ExpressionKind.rngresto: // T_RNGRESTO:
|
|||
return 2;
|
|||
case ExpressionKind.div: // T_DIV:
|
|||
case ExpressionKind.idiv: // T_IDIV:
|
|||
case ExpressionKind.mod: // T_MOD:
|
|||
case ExpressionKind.prod: // T_PROD:
|
|||
case ExpressionKind.inter: // T_INTER:
|
|||
return 3;
|
|||
case ExpressionKind.sum: // T_SUM:
|
|||
case ExpressionKind.minus: // T_MINUS:
|
|||
case ExpressionKind.union: // T_UNION:
|
|||
case ExpressionKind.diff: // T_DIFF:
|
|||
case ExpressionKind.munion: // T_MUNION:
|
|||
case ExpressionKind.seqmod_mapoverride: // T_SEQMOD_MAPOVERRIDE:
|
|||
return 4;
|
|||
/*Family of Relations*/
|
|||
case ExpressionKind.less:
|
|||
case ExpressionKind.lessequal:
|
|||
case ExpressionKind.greater:
|
|||
case ExpressionKind.greaterequal:
|
|||
case ExpressionKind.equal:
|
|||
case ExpressionKind.notequal:
|
|||
case ExpressionKind.subset:
|
|||
case ExpressionKind.elemin:
|
|||
case ExpressionKind.notelemin:
|
|||
return 5;
|
|||
/*Family of Connectives*/
|
|||
case ExpressionKind.and: // T_AND:
|
|||
return 6;
|
|||
case ExpressionKind.or: // T_OR:
|
|||
return 7;
|
|||
case ExpressionKind.implies: // T_IMPLIES:
|
|||
return 8;
|
|||
case ExpressionKind.biimplies: // T_BIIMPLIES:
|
|||
return 9;
|
|||
default:
|
|||
throw new NotImplementedException("operator not supported: " + type.ToString());
|
|||
// return 0;
|
|||
}
|
|||
}
|
|||
/*taken from antlr homepage:
|
|||
http://www.antlr.org/wiki/display/ANTLR3/Operator+precedence+parser
|
|||
*/
|
|||
int findPivot(List<BinaryOperator> operators, int startIndex, int stopIndex)
|
|||
{
|
|||
int pivot = startIndex;
|
|||
int pivotRank = GetOperatorPrecedence(operators[pivot].kind);
|
|||
for (int i = startIndex + 1; i <= stopIndex; i++)
|
|||
{
|
|||
ExpressionKind type = operators[i].kind;
|
|||
int current = GetOperatorPrecedence(type);
|
|||
bool rtl = IsRightToLeft(type);
|
|||
if (current > pivotRank || (current == pivotRank && rtl))
|
|||
{
|
|||
pivot = i;
|
|||
pivotRank = current;
|
|||
}
|
|||
}
|
|||
return pivot;
|
|||
}
|
|||
internal Expression createPrecedenceTree(
|
|||
List<Expression> expressions,
|
|||
List<BinaryOperator> operators,
|
|||
int startIndex,
|
|||
int stopIndex)
|
|||
{
|
|||
if (stopIndex == startIndex)
|
|||
return expressions[startIndex];
|
|||
int pivot = findPivot(operators, startIndex, stopIndex - 1);
|
|||
BinaryOperator result = operators[pivot];
|
|||
result.SetLeftChild(createPrecedenceTree(expressions, operators, startIndex, pivot));
|
|||
result.SetRightChild(createPrecedenceTree(expressions, operators, pivot + 1, stopIndex));
|
|||
return result;
|
|||
}
|
|||
internal Expression createPrecedenceTree(List<Expression> expressions, List<BinaryOperator> operators)
|
|||
{
|
|||
return createPrecedenceTree(expressions, operators, 0, expressions.Count - 1);
|
|||
}
|
|||
/* add error message to state. */
|
|||
private void doError(IToken aToken, string aMessage)
|
|||
{
|
|||
pState.AddErrorMessage(
|
|||
new ParserError(pState.filename, aToken, aMessage));
|
|||
}
|
|||
/* add warning message to state */
|
|||
private void doWarning(IToken id1, string p)
|
|||
{
|
|||
pState.AddWarningMessage(new ParserWarning(pState.filename, id1, p));
|
|||
}
|
|||
private void doError(string aMessage)
|
|||
{
|
|||
pState.AddErrorMessage(
|
|||
new ParserError(pState.filename, 0, 0, aMessage));
|
|||
}
|
|||
/* init global state */
|
|||
internal void initializeTopLevelParserState()
|
|||
{
|
|||
pState.ooaSystem = new MainModule();
|
|||
pState.PushResolveStack(pState.ooaSystem);
|
|||
}
|
|||
private IScope GetScope()
|
|||
{
|
|||
return pState.currentScope;
|
|||
}
|
|||
/*create a named constant*/
|
|||
internal void addNamedConst(IToken aName, Expression anExpr)
|
|||
{
|
|||
if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
|
|||
{
|
|||
/* needs to be a constant... */
|
|||
ConstantIdentifier aConst = new ConstantIdentifier(aName, anExpr, GetScope());
|
|||
OoaResolveExpressionsVisitor resolver = new OoaResolveExpressionsVisitor(pState);
|
|||
aConst.Accept(resolver);
|
|||
if (aConst.Value == null || aConst.Value.type == null || aConst.Value.kind != ExpressionKind.Value)
|
|||
{
|
|||
doError(aName, String.Format("{0} not a constant!", aName.Text));
|
|||
}
|
|||
else
|
|||
{
|
|||
aConst.SetType(aConst.Value.type);
|
|||
pState.currentScope.AddIdentifier(aConst, null);
|
|||
}
|
|||
}
|
|||
else
|
|||
doError(aName, String.Format("{0} already defined!", aName.Text));
|
|||
}
|
|||
/* create a named type; we're on top-level here */
|
|||
internal void createNamedType(IToken aName, UlyssesType aType)
|
|||
{
|
|||
// precond..
|
|||
System.Diagnostics.Debug.Assert(aName != null);
|
|||
if (aType == null)
|
|||
{
|
|||
doError(aName, String.Format("{0} lacks a type! (Type not added)", aName.Text));
|
|||
return;
|
|||
}
|
|||
if (pState.currentScope.ResolveIdentifier(aName.Text) == null)
|
|||
{
|
|||
TypeIdentifier newid = new TypeIdentifier(aName, aType, GetScope());
|
|||
aType.SetTypeIdentifier(newid);
|
|||
pState.currentScope.AddIdentifier(newid, null);
|
|||
}
|
|||
else
|
|||
doError(aName, String.Format("{0} already defined!", aName.Text));
|
|||
}
|
|||
/* create basic structure for an ooa-system descr. resolve stack TOS is now ooa-system symbols */
|
|||
internal OoActionSystemType createOoaType(IToken refinesSystemName, bool autoCons)
|
|||
{
|
|||
Identifier refinedSystem = pState.Lookup(refinesSystemName);
|
|||
OoActionSystemType refinedSystemType = null;
|
|||
if ((refinedSystem != null) && (refinedSystem.type != null))
|
|||
{
|
|||
if (refinedSystem.type.kind != TypeKind.OoActionSystemType)
|
|||
doError(refinesSystemName,
|
|||
String.Format("{0} not an object oriented action system", refinesSystemName.Text));
|
|||
else
|
|||
refinedSystemType = (OoActionSystemType)refinedSystem.type;
|
|||
}
|
|||
else if (refinesSystemName != null)
|
|||
{
|
|||
pState.AddErrorMessage(
|
|||
new ParserError(pState.filename, refinesSystemName,
|
|||
String.Format("Type that's being refined ({0}) not found!", refinesSystemName.Text)));
|
|||
}
|
|||
OoActionSystemType result = new OoActionSystemType(autoCons, refinedSystemType, null);
|
|||
// add 'self' to the symbols.. (self is a keyword, so it can't be defined)
|
|||
result.AddIdentifier(new SelfTypeIdentifier("self", result, GetScope()), null);
|
|||
pState.PushResolveStack(result);
|
|||
return result;
|
|||
}
|
|||
/* remove ooa-system symbols from resolve stack TOS */
|
|||
internal void fixupOoaType(OoActionSystemType aTypeSymbol)
|
|||
{
|
|||
if (aTypeSymbol == null)
|
|||
return;
|
|||
aTypeSymbol.SetupAnonymousName();
|
|||
if (aTypeSymbol != null)
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
internal Expression addCastExpression(Expression e, IToken cid)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(e != null);
|
|||
Expression result = new UnaryOperator(ExpressionKind.Cast, e, cid.Line, cid.CharPositionInLine);
|
|||
result.SetType(new OpaqueType(new TypeIdentifier(cid, null, GetScope())));
|
|||
pState.typesToFixUp.Add((OpaqueType)result.type);
|
|||
return result;
|
|||
}
|
|||
/* add a new ooa to the list describing the composition of action systems */
|
|||
internal void addToIdentifierList(IdentifierList top, IToken aName)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(top != null);
|
|||
Identifier aSym = pState.Lookup(aName);
|
|||
if (aSym == null)
|
|||
{
|
|||
doError(aName, String.Format("Could not find ooa-system {0}!", aName.Text));
|
|||
}
|
|||
else if ((aSym.type == null) || !(aSym.type.kind == TypeKind.OoActionSystemType))
|
|||
{
|
|||
doError(aName, String.Format("Referenced type ({0}) does not have correct type!", aName.Text));
|
|||
}
|
|||
else
|
|||
{
|
|||
OoActionSystemType aType = (OoActionSystemType)aSym.type;
|
|||
if (aType.isInSystemDescription)
|
|||
doError(aName, String.Format("Referenced type ({0}) already used in composition!", aName.Text));
|
|||
else
|
|||
aType.SetIsInSystemDescription(true);
|
|||
top.AddElement(aSym);
|
|||
}
|
|||
}
|
|||
/* does a fixup run after parsing */
|
|||
internal void fixUpRun(IdentifierList sysDescr)
|
|||
{
|
|||
// set system descr.
|
|||
pState.ooaSystem.SetSystemDescription(sysDescr);
|
|||
// fixup named types
|
|||
FixupNamedTypes();
|
|||
}
|
|||
private void FixupNamedTypes()
|
|||
{
|
|||
/*named type refs that could not be resolved in the first run, have to
|
|||
be resolved now. */
|
|||
foreach (var ntype in pState.typesToFixUp)
|
|||
{
|
|||
if (ntype.resolvedType == null)
|
|||
{
|
|||
//ntype.identifier
|
|||
Identifier asym = pState.Lookup(ntype.identifier.tokenText, ntype.identifier.definingScope);
|
|||
if ((asym == null) || (asym.kind != IdentifierKind.TypeIdentifier))
|
|||
{
|
|||
ParserError error = new ParserError(pState.filename, ntype.identifier.line, ntype.identifier.column,
|
|||
String.Format("Can not resolve {0} to a named type", ntype.identifier.tokenText));
|
|||
pState.AddErrorMessage(error);
|
|||
}
|
|||
else
|
|||
ntype.SetResolvedType(asym.type);
|
|||
}
|
|||
}
|
|||
pState.typesToFixUp.Clear();
|
|||
}
|
|||
private bool TosIsActionSystem()
|
|||
{
|
|||
return pState.currentScope is OoActionSystemType;
|
|||
}
|
|||
private int currentLine
|
|||
{
|
|||
get
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return token == null ? 0 : token.Line;
|
|||
}
|
|||
}
|
|||
private int currentPos
|
|||
{
|
|||
get
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return token == null ? 0 : token.CharPositionInLine;
|
|||
}
|
|||
}
|
|||
/* add var symbol to the current action system */
|
|||
internal void createAttribute(IToken varname, bool isStatic, bool isObs, bool isCtr, UlyssesType aType, Expression anExpr)
|
|||
{
|
|||
if (!TosIsActionSystem())
|
|||
return;
|
|||
if (aType == null)
|
|||
{
|
|||
doError(varname, String.Format("{0} lacks type!", varname.Text));
|
|||
}
|
|||
if (anExpr == null)
|
|||
{
|
|||
doError(varname, String.Format("{0} lacks initializer!", varname.Text));
|
|||
}
|
|||
if (isObs == true || isCtr == true)
|
|||
if (aType.kind != TypeKind.QrType)
|
|||
doError(varname, "'obs' or 'ctr' on attributes only allowed for qualitative types");
|
|||
AttributeIdentifier var = new AttributeIdentifier(varname, aType, GetScope(), anExpr, isStatic, isObs, isCtr);
|
|||
if (pState.currentScope.ResolveIdentifier(varname.Text) == null)
|
|||
pState.currentScope.AddIdentifier(var, null);
|
|||
else
|
|||
doError(varname, String.Format("Can not add {0}: Symbol already defined!", varname.Text));
|
|||
}
|
|||
/* create a bool type */
|
|||
internal BoolType createBoolType()
|
|||
{
|
|||
return new BoolType(null);
|
|||
}
|
|||
/* create a char type */
|
|||
internal CharType createCharType()
|
|||
{
|
|||
return new CharType(null);
|
|||
}
|
|||
/* create an int type */
|
|||
internal UlyssesType createIntType(IToken rangeLow, IToken rangeHigh)
|
|||
{
|
|||
int low = 0;
|
|||
int high = 0;
|
|||
if (rangeLow.Type == ooaLexer.T_INFTY)
|
|||
doError(rangeLow, "Infinity not supported.");
|
|||
if (rangeLow.Type == ooaLexer.T_INFTY)
|
|||
doError(rangeHigh, "Infinity not supported.");
|
|||
if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
|
|||
else if (aconst.type.kind != TypeKind.IntType)
|
|||
doError(rangeLow, "Constant must be integer");
|
|||
else
|
|||
low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else
|
|||
if (!Int32.TryParse(rangeLow.Text, out low))
|
|||
doError(rangeLow, "Can not convert to integer");
|
|||
if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
|
|||
else if (aconst.type.kind != TypeKind.IntType)
|
|||
doError(rangeHigh, "Constant must be integer");
|
|||
else
|
|||
high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else
|
|||
if (!Int32.TryParse(rangeHigh.Text, out high))
|
|||
doError(rangeHigh, "Can not convert to interger");
|
|||
if (high < low)
|
|||
doError(rangeHigh, "Lower bound greater than upper bound");
|
|||
return new IntType(low, high, null);
|
|||
}
|
|||
/* create a float type */
|
|||
internal UlyssesType createFloatType(IToken rangeLow, IToken rangeHigh)
|
|||
{
|
|||
float low = 0;
|
|||
float high = 0;
|
|||
if (rangeLow.Type == ooaLexer.T_INFTY)
|
|||
doError(rangeLow, "Infinity not supported.");
|
|||
if (rangeLow.Type == ooaLexer.T_INFTY)
|
|||
doError(rangeHigh, "Infinity not supported.");
|
|||
if (rangeLow.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeLow.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(rangeLow, String.Format("Constant {0} not found", rangeLow.Text));
|
|||
else if (aconst.type.kind != TypeKind.FloatType)
|
|||
doError(rangeLow, "Constant must be float");
|
|||
else
|
|||
low = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else if (!float.TryParse(rangeLow.Text, out low))
|
|||
doError(rangeLow, "Can not convert to float (single)");
|
|||
if (rangeHigh.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(rangeHigh.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(rangeHigh, String.Format("Constant {0} not found", rangeHigh.Text));
|
|||
else if (aconst.type.kind != TypeKind.FloatType)
|
|||
doError(rangeHigh, "Constant must be integer");
|
|||
else
|
|||
high = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else if (!float.TryParse(rangeHigh.Text, out high))
|
|||
doError(rangeHigh, "Can not convert to float (single)");
|
|||
if (high < low)
|
|||
doError(rangeHigh, "Lower bound greater than upper bound");
|
|||
/* precision */
|
|||
float afterc_low = low - (float)Convert.ToInt32(low);
|
|||
float afterc_high = high - (float)Convert.ToInt32(high);
|
|||
float precision = afterc_low < afterc_high ? afterc_low : afterc_high;
|
|||
return new FloatType(low, high, precision, null);
|
|||
}
|
|||
/* create a list of an enumerated type */
|
|||
internal UlyssesType createListEnumType(IToken alistelem)
|
|||
{
|
|||
EnumType hiddenEnumType = new EnumType(null);
|
|||
ListType result = new ListType(hiddenEnumType, 500, null);
|
|||
addToListEnumType(result, alistelem);
|
|||
return result;
|
|||
}
|
|||
/* add a new enum symbol to a list with an anonymous enumerated type */
|
|||
internal void addToListEnumType(UlyssesType aTypeSymbol, IToken otherlistelem)
|
|||
{
|
|||
EnumType enumtype = (EnumType)((ListType)aTypeSymbol).innerType;
|
|||
addToEnumType(enumtype, otherlistelem, null);
|
|||
}
|
|||
/* create a new enumerated type */
|
|||
internal UlyssesType createEnumType(IToken aRangeValue, IToken anIntegerValue)
|
|||
{
|
|||
EnumType result;
|
|||
if (anIntegerValue == null)
|
|||
result = new EnumType(null);
|
|||
else
|
|||
result = new ValuedEnumType(null);
|
|||
addToEnumType(result, aRangeValue, anIntegerValue);
|
|||
return result;
|
|||
}
|
|||
/* add a new enum symbol to the enumerated type */
|
|||
internal void addToEnumType(UlyssesType aTypeSymbol, IToken otherRangeValue, IToken anIntegerValue)
|
|||
{
|
|||
EnumType anEnum = (EnumType)aTypeSymbol;
|
|||
if (anEnum.symbolTable.Defined(otherRangeValue.Text))
|
|||
{
|
|||
doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
|
|||
return;
|
|||
}
|
|||
/* for now we allow the usage of enum-ids without specifying the actual enum type,
|
|||
* e.g., x = some_enum_id, hence all enum identifier must be globally unique.
|
|||
* This decision could be reverted at later time...
|
|||
*/
|
|||
Identifier sym = pState.Lookup(otherRangeValue);
|
|||
if (sym != null)
|
|||
{
|
|||
doError(otherRangeValue, String.Format("Element '{0}' already defined!", otherRangeValue.Text));
|
|||
return;
|
|||
}
|
|||
EnumIdentifier enumval;
|
|||
if (anIntegerValue == null)
|
|||
{
|
|||
if (aTypeSymbol is ValuedEnumType)
|
|||
{
|
|||
doError(otherRangeValue, String.Format("Element '{0}' needs integer value!", otherRangeValue.Text));
|
|||
return;
|
|||
}
|
|||
enumval = new EnumIdentifier(otherRangeValue, (EnumType)aTypeSymbol, GetScope());
|
|||
}
|
|||
else
|
|||
{
|
|||
if (!(aTypeSymbol is ValuedEnumType))
|
|||
{
|
|||
doError(otherRangeValue, String.Format("Element '{0}' must not have integer value!", otherRangeValue.Text));
|
|||
return;
|
|||
}
|
|||
enumval = new EnumIdentifier(otherRangeValue, Int32.Parse(anIntegerValue.Text), (EnumType)aTypeSymbol, GetScope());
|
|||
}
|
|||
((EnumType)aTypeSymbol).AddEnumSymbol(enumval);
|
|||
/* add the enum id to 'global' state */
|
|||
pState.currentScope.AddIdentifier(enumval, null);
|
|||
}
|
|||
/* get a named type */
|
|||
internal UlyssesType getNamedType(IToken aType)
|
|||
{
|
|||
UlyssesType result = null;
|
|||
Identifier sym = pState.Lookup(aType);
|
|||
if (sym == null)
|
|||
{
|
|||
/* we might not have seen this type yet - so do a fixup run later */
|
|||
result = new OpaqueType(new TypeIdentifier(aType, null, GetScope()));
|
|||
pState.typesToFixUp.Add((OpaqueType)result);
|
|||
}
|
|||
else if (sym.kind == IdentifierKind.TypeIdentifier)
|
|||
result = ((TypeIdentifier)sym).type;
|
|||
else
|
|||
doError(aType, "Not a named type symbol!");
|
|||
return result;
|
|||
}
|
|||
/* create a list type */
|
|||
internal UlyssesType createListType(IToken numOfElements, UlyssesType innertype)
|
|||
{
|
|||
if (innertype == null)
|
|||
doError(numOfElements, "List type lacks proper element type (null)");
|
|||
int numElems = 0;
|
|||
if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
|
|||
else if (aconst.type.kind != TypeKind.IntType)
|
|||
doError(numOfElements, "Constant must be integer");
|
|||
else
|
|||
numElems = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else
|
|||
{
|
|||
if (!Int32.TryParse(numOfElements.Text, out numElems))
|
|||
doError(numOfElements, "Not an integer");
|
|||
if (numElems <= 0)
|
|||
doError(numOfElements, "Number of elements in a list must be >= 1");
|
|||
}
|
|||
ListType result = new ListType(innertype, numElems, null);
|
|||
return result;
|
|||
}
|
|||
/* create a map type */
|
|||
internal UlyssesType createMapType(IToken numOfElements, UlyssesType mapfromtype, UlyssesType maptotype)
|
|||
{
|
|||
if (mapfromtype == null)
|
|||
doError(numOfElements, "Map: From-type not set (null)");
|
|||
if (maptotype == null)
|
|||
doError(numOfElements, "Map: To-type not set (null)");
|
|||
int max = 0;
|
|||
if (numOfElements.Type == ooaLexer.T_IDENTIFIER)
|
|||
{
|
|||
// see whether we can find the constant
|
|||
Identifier aconst = pState.currentScope.ResolveIdentifier(numOfElements.Text);
|
|||
if (aconst == null || aconst.kind != IdentifierKind.Constant)
|
|||
doError(numOfElements, String.Format("Constant {0} not found", numOfElements.Text));
|
|||
else if (aconst.type.kind != TypeKind.IntType)
|
|||
doError(numOfElements, "Constant must be integer");
|
|||
else
|
|||
max = ((ValueExpression<int>)((ConstantIdentifier)aconst).Value).value;
|
|||
}
|
|||
else
|
|||
if (!Int32.TryParse(numOfElements.Text, out max))
|
|||
doError(numOfElements, "Not an integer");
|
|||
MapType result = new MapType(mapfromtype, maptotype, max, null);
|
|||
return result;
|
|||
}
|
|||
/* create a tuple type */
|
|||
internal UlyssesType createTupleType(UlyssesType aType)
|
|||
{
|
|||
TupleType result = new TupleType(null);
|
|||
if (aType == null)
|
|||
doError("Unknown inner type.");
|
|||
else
|
|||
addToTupleType(result, aType);
|
|||
return result;
|
|||
}
|
|||
/* add inner type to tuple */
|
|||
internal void addToTupleType(UlyssesType aTypeSymbol, UlyssesType anotherType)
|
|||
{
|
|||
if (anotherType == null)
|
|||
doError("Unknown inner type.");
|
|||
else
|
|||
{
|
|||
TupleType tuple = (TupleType)aTypeSymbol;
|
|||
tuple.AddType(anotherType);
|
|||
}
|
|||
}
|
|||
/* create a QR type */
|
|||
internal UlyssesType createQrType(IToken alandmark)
|
|||
{
|
|||
QrType result = new QrType(null);
|
|||
addToQrType(result, alandmark);
|
|||
return result;
|
|||
}
|
|||
/* add another landmark to QR type */
|
|||
private void addToQrType(UlyssesType aTypeSymbol, IToken otherlandmark)
|
|||
{
|
|||
Identifier sym = pState.Lookup(otherlandmark);
|
|||
if (sym != null)
|
|||
{
|
|||
doError(otherlandmark, String.Format("Redifinition of {0}", otherlandmark.Text));
|
|||
return;
|
|||
}
|
|||
LandmarkIdentifier lndmrk = new LandmarkIdentifier(otherlandmark, (QrType)aTypeSymbol, GetScope());
|
|||
((QrType)aTypeSymbol).AddLandmark(lndmrk);
|
|||
}
|
|||
/* gets called after a simple type has been constructed. used to define an internal name*/
|
|||
internal void fixupSimpleType(UlyssesType aTypeSymbol)
|
|||
{
|
|||
if (aTypeSymbol != null)
|
|||
aTypeSymbol.SetupAnonymousName();
|
|||
}
|
|||
/* gets called after a simple or complex type has been constructed. used to define an internal name */
|
|||
internal void fixupComplexType(UlyssesType aTypeSymbol)
|
|||
{
|
|||
if (aTypeSymbol != null)
|
|||
aTypeSymbol.SetupAnonymousName();
|
|||
}
|
|||
/* create a method symbol */
|
|||
internal FunctionIdentifier createMethodSymbol(IToken mname)
|
|||
{
|
|||
Identifier sym = pState.Lookup(mname);
|
|||
if (sym != null)
|
|||
{
|
|||
doError(mname, String.Format("Redefinition of {0}", mname.Text));
|
|||
return null;
|
|||
}
|
|||
FunctionType funtype = new FunctionType(FunctionTypeEnum.Method, new LinkedList<UlyssesType>(), null);
|
|||
MethodIdentifier msym = new MethodIdentifier(mname, funtype, GetScope());
|
|||
funtype.SetTypeIdentifier(msym);
|
|||
pState.currentScope.AddIdentifier(msym, null);
|
|||
pState.PushResolveStack(msym);
|
|||
return msym;
|
|||
}
|
|||
/* remove local method symbols from resolution stack again */
|
|||
private void popResolveStack(FunctionIdentifier newMethod)
|
|||
{
|
|||
if (newMethod != null)
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
/* add a return type to a method */
|
|||
internal void setMethodReturnType(FunctionIdentifier newMethod, UlyssesType rt)
|
|||
{
|
|||
if (newMethod == null)
|
|||
return;
|
|||
if (rt == null)
|
|||
doError(String.Format("Method {0} has no return type (null)", newMethod.tokenText));
|
|||
/* set return type */
|
|||
((FunctionType)newMethod.type).SetReturnType(rt);
|
|||
/* add hidden return parameter */
|
|||
if (newMethod.symbolTable.Defined("result"))
|
|||
{
|
|||
doError(String.Format("Method {0} defines 'result'", newMethod.tokenText));
|
|||
return;
|
|||
}
|
|||
ParameterIdentifier returnval = new ParameterIdentifier("result", rt, GetScope());
|
|||
newMethod.symbolTable.AddIdentifier(returnval);
|
|||
}
|
|||
/* add a parameter to a method */
|
|||
internal void addMethodParameter(FunctionIdentifier newMethod, IToken paramName, UlyssesType atype)
|
|||
{
|
|||
if (newMethod == null)
|
|||
return;
|
|||
if (atype == null)
|
|||
doError(paramName, "Parameter has no type (null)");
|
|||
if (newMethod.symbolTable.Defined(paramName.Text) == true)
|
|||
{
|
|||
doError(paramName, String.Format("Parameter {0} already defined", paramName.Text));
|
|||
return;
|
|||
}
|
|||
// add parameter to scope
|
|||
ParameterIdentifier param = new ParameterIdentifier(paramName, atype, GetScope());
|
|||
newMethod.AddParameter(param);
|
|||
// add type of param to signature
|
|||
FunctionType ftype = (FunctionType)newMethod.type;
|
|||
ftype.AddParameterType(atype);
|
|||
}
|
|||
/* set method body of a method */
|
|||
internal void addMethodBody(FunctionIdentifier newMethod, Block statements)
|
|||
{
|
|||
if (newMethod == null)
|
|||
return;
|
|||
if (statements == null)
|
|||
doError(String.Format("{0} has empty body (null)",
|
|||
((FunctionType)newMethod.type).functionType == FunctionTypeEnum.Method ? "Method" : "Action"));
|
|||
newMethod.SetBody(statements);
|
|||
}
|
|||
/* create a continuous action */
|
|||
internal FunctionIdentifier createNamedContinuousAction(IToken cactionname, FunctionTypeEnum actionTypeEnum)
|
|||
{
|
|||
return createNamedAction(cactionname, actionTypeEnum);
|
|||
}
|
|||
/* create a named action */
|
|||
internal FunctionIdentifier createNamedAction(IToken actionname, FunctionTypeEnum actionType)
|
|||
{
|
|||
Identifier sym = pState.Lookup(actionname);
|
|||
if (sym != null)
|
|||
{
|
|||
doError(actionname, "Symbol already defined.");
|
|||
return null;
|
|||
}
|
|||
FunctionType atype = new FunctionType(actionType, new LinkedList<UlyssesType>(), null);
|
|||
NamedActionIdentifier action = new NamedActionIdentifier(actionname, atype, GetScope());
|
|||
atype.SetTypeIdentifier(action);
|
|||
pState.currentScope.AddIdentifier(action, null);
|
|||
pState.PushResolveStack(action);
|
|||
return action;
|
|||
}
|
|||
/* add body of action */
|
|||
internal void addActionBody(FunctionIdentifier newAction, GuardedCommand body)
|
|||
{
|
|||
// we need a wrapper around the guarded command..
|
|||
Block bdy = new SeqBlock(currentLine, currentPos);
|
|||
bdy.AddStatement(body);
|
|||
addMethodBody(newAction, bdy);
|
|||
}
|
|||
/* add constraints of cont. action */
|
|||
internal void addContinuousActionBody(FunctionIdentifier newAction, GuardedCommand constraints)
|
|||
{
|
|||
Block bdy = new SeqBlock(currentLine, currentPos);
|
|||
bdy.AddStatement(constraints);
|
|||
addMethodBody(newAction, bdy);
|
|||
}
|
|||
/* create a guarded command */
|
|||
internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy)
|
|||
{
|
|||
if (bdy == null)
|
|||
doError("Guarded command without body (null)!");
|
|||
if (expr == null)
|
|||
doError("Guarded command without guard (null)!");
|
|||
GuardedCommand result = new GuardedCommand(expr, bdy, currentLine, currentPos);
|
|||
return result;
|
|||
}
|
|||
internal GuardedCommand createGuardedCommandStatement(Expression expr, Block bdy, bool isQualitative)
|
|||
{
|
|||
GuardedCommand result = createGuardedCommandStatement(expr, bdy);
|
|||
result.SetIsQualitative(isQualitative);
|
|||
return result;
|
|||
}
|
|||
/* add statements to list */
|
|||
internal void addToStatementList(Block top, Statement stmt)
|
|||
{
|
|||
if (stmt == null)
|
|||
doError("Can not add statement: null!");
|
|||
top.AddStatement(stmt);
|
|||
}
|
|||
/* create a Kill statement */
|
|||
internal Statement createKillStatement(IToken aname)
|
|||
{
|
|||
Identifier sym = pState.Lookup(aname);
|
|||
if (sym == null)
|
|||
doError(aname, "Not defined");
|
|||
KillStatement result = new KillStatement(sym, aname.Line, aname.CharPositionInLine);
|
|||
return result;
|
|||
}
|
|||
/* create a Skip statement */
|
|||
internal Statement createSkipStatement()
|
|||
{
|
|||
return new SkipStatement(currentLine, currentPos);
|
|||
}
|
|||
/* create an Abort statement */
|
|||
internal Statement createAbortStatement()
|
|||
{
|
|||
return new AbortStatement(currentLine, currentPos);
|
|||
}
|
|||
/* creates a prioritized composition block */
|
|||
internal Block createPrioBlock(Block top)
|
|||
{
|
|||
return new PrioBlock(top, currentLine, currentPos);
|
|||
}
|
|||
/* creates a nondeterministically composed block */
|
|||
internal Block createNondetBlock(Block top)
|
|||
{
|
|||
return new NondetBlock(top, currentLine, currentPos);
|
|||
}
|
|||
/* creates a sequentially composed block */
|
|||
internal Block createSeqBlock(Block top)
|
|||
{
|
|||
return new SeqBlock(top, currentLine, currentPos);
|
|||
}
|
|||
/* adds a filter expression to seq block */
|
|||
private void addSeqBlockExpression(Block seqList, Expression sexpr)
|
|||
{
|
|||
seqList.SetFilter(sexpr); /*gets transformed to guarded command in resolvevisitor!*/
|
|||
}
|
|||
/* create a self identifier */
|
|||
internal IdentifierExpression createSelfIdentifierExpression(IToken self)
|
|||
{
|
|||
Identifier id = pState.Lookup("self");
|
|||
if (id == null)
|
|||
{
|
|||
doError(self, "Can not resolve 'self'");
|
|||
return null;
|
|||
}
|
|||
IdentifierExpression result = new IdentifierExpression(id, self.Line, self.CharPositionInLine);
|
|||
result.setIsSelf(true);
|
|||
return result;
|
|||
}
|
|||
/* build up identifier tree... */
|
|||
internal Expression createIdentifierAccessExpression(IdentifierExpression aself, IToken token)
|
|||
{
|
|||
Identifier someid = pState.Lookup(token.Text, GetScope());
|
|||
Identifier self = pState.Lookup("self");
|
|||
if (someid != null)
|
|||
{
|
|||
switch (someid.kind)
|
|||
{
|
|||
/* all method and attribute accesses are prefixed by self */
|
|||
case IdentifierKind.AttributeIdentifier:
|
|||
case IdentifierKind.MethodIdentifier:
|
|||
if (self == null)
|
|||
doError(token, "Self access of method: Can not find 'self' symbol! (internal error)");
|
|||
aself = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
|
|||
aself.setIsSelf(true);
|
|||
break;
|
|||
default:
|
|||
break;
|
|||
}
|
|||
}
|
|||
IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
|
|||
if (aself != null)
|
|||
return new AccessExpression(aself, ident, token.Line, token.CharPositionInLine);
|
|||
else
|
|||
return ident;
|
|||
}
|
|||
internal AccessExpression addIdentifierAccessExpression(Expression parent, IToken token)
|
|||
{
|
|||
IdentifierExpression ident = new UnresolvedIdentifierExpression(token, GetScope());
|
|||
return new AccessExpression(parent, ident, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* we have a primed id; prime the complete subtree.. */
|
|||
internal void setIdentifierExpressionPrimed(ref Expression result, IToken token)
|
|||
{
|
|||
Expression priming = new UnaryOperator(ExpressionKind.Primed, result, token.Line, token.CharPositionInLine);
|
|||
result = priming;
|
|||
}
|
|||
/* create a fold operation */
|
|||
internal Expression createFoldExpression(Expression result, IToken afold, Expression initval, Expression anexpr)
|
|||
{
|
|||
ExpressionKind akind = ExpressionKind.foldLR;
|
|||
if (afold.Type == ooaLexer.T_FOLDLR)
|
|||
akind = ExpressionKind.foldLR;
|
|||
else if (afold.Type == ooaLexer.T_FOLDRL)
|
|||
akind = ExpressionKind.foldRL;
|
|||
else
|
|||
System.Diagnostics.Debug.Assert(false);
|
|||
TernaryOperator op = new TernaryOperator(akind, result, initval, anexpr, currentLine, currentPos, GetScope());
|
|||
return op;
|
|||
}
|
|||
/* create a method access */
|
|||
internal CallExpression createMethodAccessExpression(Expression subexpr, List<Expression> m_params, IToken token)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(subexpr != null);
|
|||
return new CallExpression(subexpr, m_params, token.Line, token.CharPositionInLine, GetScope());
|
|||
}
|
|||
/* create a tuple or map access */
|
|||
internal TupleMapAccessExpression createTupleMapAccessExpression(Expression subexpr, Expression ac, IToken token)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(subexpr != null);
|
|||
return new TupleMapAccessExpression(subexpr, ac, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* create a method call statement; has to be resolved in a second run */
|
|||
internal Statement createCallStatement(Expression aqname)
|
|||
{
|
|||
return new Call(aqname, currentLine, currentPos);
|
|||
}
|
|||
/* create a single assignment statement */
|
|||
internal Statement createSingleAssignmentStatement(Expression aqname, Expression aexp)
|
|||
{
|
|||
Assignment result = new Assignment(aqname, aexp, null, currentLine, currentPos);
|
|||
return result;
|
|||
}
|
|||
/* create a multi-assignment statement; has to be resolved in a second run */
|
|||
internal Statement createMultipleAssignmentStatementLHS(Expression aqname)
|
|||
{
|
|||
return new Assignment(aqname, null, null, currentLine, currentPos);
|
|||
}
|
|||
/* adds an expression to the multi-assign */
|
|||
internal void addMutlipleAssignmentStatementRHS(Statement result, Expression mexp)
|
|||
{
|
|||
((Assignment)result).AddValue(mexp);
|
|||
}
|
|||
/* adds a LHS-var to the multi assign */
|
|||
internal void addMultipleAssignmentStatementLHS(Statement result, Expression malhs)
|
|||
{
|
|||
((Assignment)result).AddPlace(malhs);
|
|||
}
|
|||
/* pop an assignment statement from the resolve stack */
|
|||
internal void popAssignmentOffResolveStack(Statement result)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(ReferenceEquals(result, pState.currentScope));
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
/* pushes the assignment statement onto resolve stack. */
|
|||
internal void pushAssignmentOnResolveStack(Statement result)
|
|||
{
|
|||
System.Diagnostics.Debug.Assert(result is Assignment);
|
|||
pState.PushResolveStack((Assignment)result);
|
|||
}
|
|||
/* adds a nondet-assignment constraint */
|
|||
internal void addConstraintToAssignment(Statement result, Expression ndexp)
|
|||
{
|
|||
((Assignment)result).SetNondetExpression(ndexp);
|
|||
}
|
|||
/* add a named action call to do-od block */
|
|||
internal void addNamedActionCallToBlockList(Block top, IToken aname, List<Expression> m_params, IToken maptoken, Expression amapexpression)
|
|||
{
|
|||
Identifier id = pState.Lookup(aname);
|
|||
if (id == null)
|
|||
{
|
|||
doError(aname, "Could not find named action");
|
|||
return;
|
|||
}
|
|||
Expression callexpr;
|
|||
if (id.kind == IdentifierKind.MethodIdentifier)
|
|||
{
|
|||
doError(aname, "Method access in do-od block not allowed.");
|
|||
return;
|
|||
// access via self
|
|||
/*
|
|||
Identifier self = pState.Lookup("self");
|
|||
if (self == null)
|
|||
doError(aname, "Self access of method: Can not find 'self' symbol! (internal error)");
|
|||
IdentifierExpression aself = new IdentifierExpression(self, aname.Line, aname.CharPositionInLine);
|
|||
aself.setIsSelf(true);
|
|||
callexpr = new CallExpression(
|
|||
new AccessExpression(aself,
|
|||
new IdentifierExpression(id, aname.Line, aname.CharPositionInLine), aname.Line, aname.CharPositionInLine),
|
|||
m_params, aname.Line, aname.CharPositionInLine, GetScope());
|
|||
*/
|
|||
}
|
|||
else
|
|||
callexpr = new CallExpression(
|
|||
new IdentifierExpression(id, aname.Line, aname.CharPositionInLine),
|
|||
m_params, aname.Line, aname.CharPositionInLine, GetScope());
|
|||
if (amapexpression != null)
|
|||
{
|
|||
ExpressionKind akind = ExpressionKind.foldLR;
|
|||
if (maptoken.Type == ooaLexer.T_FOLDLR)
|
|||
akind = ExpressionKind.foldLR;
|
|||
else if (maptoken.Type == ooaLexer.T_FOLDRL)
|
|||
akind = ExpressionKind.foldRL;
|
|||
else
|
|||
System.Diagnostics.Debug.Assert(false);
|
|||
callexpr = new TernaryOperator(akind, callexpr, null, amapexpression,
|
|||
currentLine, currentPos, GetScope());
|
|||
}
|
|||
Call statement = new Call(callexpr, currentLine, currentPos);
|
|||
top.AddStatement(statement);
|
|||
}
|
|||
/*adds skip statement instead of call to do-od block*/
|
|||
internal void addSkipStatementToBlockList(Block top)
|
|||
{
|
|||
top.AddStatement(new SkipStatement(currentLine, currentPos));
|
|||
}
|
|||
/* add anonymous action to do-od block */
|
|||
internal void addToBlockList(Block top, Statement gcmd)
|
|||
{
|
|||
if (gcmd != null)
|
|||
top.AddStatement(gcmd);
|
|||
}
|
|||
/* add the do-od block to the action system type */
|
|||
internal void addActionBlock(OoActionSystemType aTypeSymbol, Block bl)
|
|||
{
|
|||
aTypeSymbol.SetDoOdBlock(bl);
|
|||
}
|
|||
/* push block */
|
|||
internal void pushBlockToResolveStack(Block toPush)
|
|||
{
|
|||
pState.PushResolveStack(toPush);
|
|||
}
|
|||
/* pop block */
|
|||
internal void popBlockFromResolveStack(Block toPop)
|
|||
{
|
|||
if (toPop != null)
|
|||
{
|
|||
object anobject = pState.currentScope as Block;
|
|||
System.Diagnostics.Debug.Assert(Object.ReferenceEquals(anobject, toPop));
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
}
|
|||
/* add block var */
|
|||
internal void addBlockVariable(Block seqList, IToken varname, UlyssesType aType)
|
|||
{
|
|||
if (aType == null)
|
|||
{
|
|||
doError(varname, String.Format("{0} lacks type!", varname.Text));
|
|||
}
|
|||
try
|
|||
{
|
|||
seqList.AddIdentifier(new LocalVariableIdentifier(varname, aType, GetScope()));
|
|||
}
|
|||
catch (ArgumentException)
|
|||
{
|
|||
doError(varname, String.Format("{0} redefined!", varname.Text));
|
|||
}
|
|||
}
|
|||
internal QualitativeConstraintStatement createTwoVarConstraintStatement(IToken id1, IToken id2, QualitativeConstraintOperation op)
|
|||
{
|
|||
Identifier var1 = pState.Lookup(id1);
|
|||
if (var1 == null)
|
|||
{
|
|||
var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
|
|||
var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
|
|||
GetScope().AddIdentifier(var1, null);
|
|||
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
|
|||
}
|
|||
Identifier var2 = pState.Lookup(id2);
|
|||
if (var2 == null)
|
|||
{
|
|||
var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
|
|||
var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
|
|||
GetScope().AddIdentifier(var2, null);
|
|||
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
|
|||
}
|
|||
QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, op, id1.Line, id1.CharPositionInLine);
|
|||
return result;
|
|||
}
|
|||
internal QualitativeConstraintStatement createQualEqualConstraintStatement(IToken id1, IToken id2)
|
|||
{
|
|||
return createTwoVarConstraintStatement(id1, id2, QualitativeConstraintOperation.Equal);
|
|||
}
|
|||
internal QualitativeConstraintStatement createQualArithConstraintStatement(IToken id1, IToken id2, IToken id3, IToken op)
|
|||
{
|
|||
Identifier var1 = pState.Lookup(id1);
|
|||
if (var1 == null)
|
|||
{
|
|||
var1 = new ExpressionVariableIdentifier(id1.Text, id1.Line, id1.CharPositionInLine);
|
|||
var1.SetType(new AnyType((ExpressionVariableIdentifier)var1));
|
|||
GetScope().AddIdentifier(var1, null);
|
|||
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id1.Text));
|
|||
}
|
|||
Identifier var2 = pState.Lookup(id2);
|
|||
if (var2 == null)
|
|||
{
|
|||
var2 = new ExpressionVariableIdentifier(id2.Text, id2.Line, id2.CharPositionInLine);
|
|||
var2.SetType(new AnyType((ExpressionVariableIdentifier)var2));
|
|||
GetScope().AddIdentifier(var2, null);
|
|||
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id2.Text));
|
|||
}
|
|||
Identifier var3 = pState.Lookup(id3);
|
|||
if (var3 == null)
|
|||
{
|
|||
var3 = new ExpressionVariableIdentifier(id3.Text, id3.Line, id3.CharPositionInLine);
|
|||
var3.SetType(new AnyType((ExpressionVariableIdentifier)var3));
|
|||
GetScope().AddIdentifier(var3, null);
|
|||
doWarning(id1, String.Format("Free variable in qualitative constraint: '{0}'.", id3.Text));
|
|||
}
|
|||
QualitativeConstraintOperation operation;
|
|||
switch (op.Type)
|
|||
{
|
|||
case ooaParser.T_SUM:
|
|||
operation = QualitativeConstraintOperation.Sum;
|
|||
break;
|
|||
case ooaParser.T_DIFF:
|
|||
operation = QualitativeConstraintOperation.Diff;
|
|||
break;
|
|||
case ooaParser.T_PROD:
|
|||
operation = QualitativeConstraintOperation.Prod;
|
|||
break;
|
|||
default:
|
|||
doError(op, String.Format("'{0}' unknown operation", op.Text));
|
|||
return null;
|
|||
}
|
|||
QualitativeConstraintStatement result = new QualitativeConstraintStatement(var1, var2, var3, operation, id1.Line, id1.CharPositionInLine);
|
|||
return result;
|
|||
}
|
|||
internal QualitativeConstraintStatement createQualDerivConstraintStatement(IToken id1, IToken derivid)
|
|||
{
|
|||
return createTwoVarConstraintStatement(id1, derivid, QualitativeConstraintOperation.Deriv);
|
|||
}
|
|||
/* creates a general binary operator without any children */
|
|||
internal BinaryOperator createBinaryOperator(ExpressionKind akind)
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return new BinaryOperator(akind, null, null, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* creates a general unary operator without child */
|
|||
internal UnaryOperator createUnaryOperator(ExpressionKind unaryOperatorType)
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return new UnaryOperator(unaryOperatorType, null, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* create a conditional expression */
|
|||
internal Expression createConditionalExpression(Expression ce, Expression te, Expression ee, IToken ef)
|
|||
{
|
|||
return new TernaryOperator(ExpressionKind.conditional, ce, te, ee, ef.Line, ef.CharPositionInLine, GetScope());
|
|||
}
|
|||
/* create a quantifier expression */
|
|||
internal Quantifier createQuantifierExpression(IToken t)
|
|||
{
|
|||
Quantifier result = null;
|
|||
if (t.Type == T_FORALL)
|
|||
result = new ForallQuantifier(null, t.Line, t.CharPositionInLine);
|
|||
else
|
|||
result = new ExistsQuantifier(null, t.Line, t.CharPositionInLine);
|
|||
pState.PushResolveStack(result);
|
|||
return result;
|
|||
}
|
|||
/* add a bound variable to the quantifier */
|
|||
internal void addBoundVarToQuantifierExpression(Quantifier result, IToken id, UlyssesType id_type)
|
|||
{
|
|||
/*note: this might be a bit harsh, but for now it's easier to demand uniquely named vars,
|
|||
without any hiding. Could be fixed in searching only the first resolve level for
|
|||
dupes..
|
|||
*/
|
|||
Identifier sym = pState.Lookup(id);
|
|||
if (sym != null)
|
|||
doError(id, String.Format("{0} already defined!", id.Text));
|
|||
else
|
|||
{
|
|||
if (id_type == null)
|
|||
doError(id, String.Format("{0} lacks type (null).", id.Text));
|
|||
Identifier newvar = new ExpressionVariableIdentifier(id, id_type, GetScope());
|
|||
result.AddIdentifier(newvar, null);
|
|||
}
|
|||
}
|
|||
/* add the expression to the quantifier */
|
|||
internal void addExpressionToQuantifier(Quantifier result, Expression e)
|
|||
{
|
|||
result.SetChild(e);
|
|||
}
|
|||
/* remove local variables from resolve stack */
|
|||
internal void removeBoundVarsFromResolveStack(Quantifier result)
|
|||
{
|
|||
if (result != null)
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
/* create a bool constant */
|
|||
internal LeafExpression createBoolConstant(bool p)
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return new ValueExpression<bool>(p, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* create a nil */
|
|||
internal LeafExpression createNullPointerConstant()
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return new ValueExpression<object>(null, token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* create a 'self' identifier */
|
|||
internal LeafExpression createSelfPointer()
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
Identifier self = pState.Lookup("self");
|
|||
if (self == null)
|
|||
{
|
|||
doError(token, "Could not resolve 'self'");
|
|||
return new UnresolvedIdentifierExpression(token, GetScope());
|
|||
}
|
|||
IdentifierExpression result = new IdentifierExpression(self, token.Line, token.CharPositionInLine);
|
|||
result.setIsSelf(true);
|
|||
return result;
|
|||
}
|
|||
/* create a float const */
|
|||
internal LeafExpression createFloatConstant(IToken t_fl)
|
|||
{
|
|||
return new ValueExpression<double>(double.Parse(t_fl.Text, System.Globalization.CultureInfo.InvariantCulture), t_fl.Line, t_fl.CharPositionInLine);
|
|||
}
|
|||
/* create int const */
|
|||
internal LeafExpression createIntConstant(IToken t_in)
|
|||
{
|
|||
return new ValueExpression<int>(int.Parse(t_in.Text), t_in.Line, t_in.CharPositionInLine);
|
|||
}
|
|||
/* set children of binary operator*/
|
|||
internal Expression addBinaryExpression(BinaryOperator binexpr, Expression expr, Expression e2)
|
|||
{
|
|||
binexpr.SetLeftChild(expr);
|
|||
binexpr.SetRightChild(e2);
|
|||
return binexpr;
|
|||
}
|
|||
/* set child of unary expr */
|
|||
internal Expression addUnaryExpression(UnaryOperator unexpr, Expression e)
|
|||
{
|
|||
if (unexpr != null)
|
|||
{
|
|||
unexpr.SetChild(e);
|
|||
return unexpr;
|
|||
}
|
|||
else
|
|||
return e;
|
|||
}
|
|||
/* create a list */
|
|||
internal ListConstructor createInitializedList()
|
|||
{
|
|||
IToken nexttoken = input.LT(1);
|
|||
return new ListConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
|
|||
}
|
|||
/* add an element to the list */
|
|||
internal void addListElement(ListConstructor result, Expression e)
|
|||
{
|
|||
result.AddElement(e);
|
|||
}
|
|||
/* push list comprehension vars on resolve stack */
|
|||
internal void pushListVarsOnResolveStack(ListConstructor result)
|
|||
{
|
|||
pState.PushResolveStack(result);
|
|||
}
|
|||
/* pop list comprehension vars from resolve stack */
|
|||
internal void popListVarsFromResolveStack(ListConstructor result)
|
|||
{
|
|||
if (result != null)
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
/* set list comprehension expression */
|
|||
internal void addListComprExpr(ListConstructor result, Expression e)
|
|||
{
|
|||
result.SetComprehension(e);
|
|||
}
|
|||
/* add list comprehension variable */
|
|||
internal void addListComprVar(ListConstructor result, IToken id, UlyssesType t1)
|
|||
{
|
|||
Identifier sym = pState.Lookup(id);
|
|||
if (sym != null)
|
|||
{
|
|||
/* see notes in quantifier*/
|
|||
doError(id, String.Format("{0} already defined.", id.Text));
|
|||
}
|
|||
else
|
|||
{
|
|||
ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id, t1, GetScope());
|
|||
result.AddIdentifier(newvar, null);
|
|||
}
|
|||
}
|
|||
/* converts a string into a list of char */
|
|||
internal ListConstructor createStringConstant(IToken t_l)
|
|||
{
|
|||
ListConstructor result = new ListConstructor(t_l.Line, t_l.CharPositionInLine);
|
|||
foreach (char c in t_l.Text.Substring(1, t_l.Text.Length - 2))
|
|||
result.AddElement(new ValueExpression<char>(c, t_l.Line, t_l.CharPositionInLine));
|
|||
return result;
|
|||
}
|
|||
/* creates an empty map */
|
|||
internal Expression createEmptyMap()
|
|||
{
|
|||
IToken token = input.LT(-1);
|
|||
return new MapConstructor(token.Line, token.CharPositionInLine);
|
|||
}
|
|||
/* create a map and populate it with two items.. */
|
|||
internal Expression createMap(Expression e1, Expression e2, IToken am)
|
|||
{
|
|||
MapConstructor result = new MapConstructor(am.Line, am.CharPositionInLine);
|
|||
result.AddItem(e1, e2);
|
|||
return result;
|
|||
}
|
|||
/* add a key/value pair to a map */
|
|||
internal void addToMap(Expression map, Expression e3, Expression e4)
|
|||
{
|
|||
((MapConstructor)map).AddItem(e3, e4);
|
|||
}
|
|||
/* create a set */
|
|||
internal SetConstructor createSet()
|
|||
{
|
|||
IToken nexttoken = input.LT(1);
|
|||
SetConstructor result = new SetConstructor(nexttoken.Line, nexttoken.CharPositionInLine);
|
|||
return result;
|
|||
}
|
|||
/* add item to set */
|
|||
internal void addToSet(Expression result, Expression e2)
|
|||
{
|
|||
((SetConstructor)result).AddItem(e2);
|
|||
}
|
|||
/* remove set comprehension variables from resolution stack */
|
|||
internal void popSetVarsFromResolveStack(SetConstructor _set)
|
|||
{
|
|||
if (_set != null)
|
|||
pState.PopResolveStack();
|
|||
}
|
|||
/* add set comprehension variables to resolution stack */
|
|||
internal void pushSetVarsOnResolveStack(SetConstructor _set)
|
|||
{
|
|||
pState.PushResolveStack(_set);
|
|||
}
|
|||
/* set comprehension expression fro set */
|
|||
internal void addSetComprExpr(SetConstructor _set, Expression epx)
|
|||
{
|
|||
_set.SetComprehension(epx);
|
|||
}
|
|||
/* add local set compr. variable */
|
|||
internal void addSetComprVar(SetConstructor _set, IToken id1, UlyssesType t1)
|
|||
{
|
|||
Identifier sym = pState.Lookup(id1);
|
|||
if (sym != null)
|
|||
doError(id1, String.Format("{0} already defined!", id1.Text));
|
|||
else
|
|||
{
|
|||
ExpressionVariableIdentifier newvar = new ExpressionVariableIdentifier(id1, t1, GetScope());
|
|||
_set.AddIdentifier(newvar, null);
|
|||
}
|
|||
}
|
|||
/* check whether identifier p is a tuple type */
|
|||
internal bool isTuple(string p)
|
|||
{
|
|||
Identifier sym = pState.Lookup(p);
|
|||
return (sym != null)
|
|||
&& (sym.kind == IdentifierKind.TypeIdentifier)
|
|||
&& (sym.type.kind == TypeKind.TupleType);
|
|||
}
|
|||
/* create an initialized tuple */
|
|||
internal Expression createInitializedTuple(IToken aName, System.Collections.Generic.List<Expression> m_params)
|
|||
{
|
|||
Identifier sym = pState.Lookup(aName);
|
|||
if ((sym == null) || !(sym.type is TupleType))
|
|||
{
|
|||
doError(aName, "Not a tuple type!");
|
|||
return null;
|
|||
}
|
|||
TupleType atuple = (TupleType)sym.type;
|
|||
if (atuple.innerTypes.Count != m_params.Count)
|
|||
{
|
|||
doError(aName, "Number of parameters does not match type definition!");
|
|||
return null;
|
|||
}
|
|||
return new TupleConstructor(sym, m_params, aName.Line, aName.CharPositionInLine);
|
|||
}
|
|||
/* create an reference expression: (<expression>).xyz */
|
|||
internal Expression createExpressionReference(Expression e, Expression aref, IToken atoken)
|
|||
{
|
|||
AccessExpression result = new AccessExpression(e, aref, atoken.Line, atoken.CharPositionInLine);
|
|||
return result;
|
|||
}
|
|||
/* gets called when we are parsing attributes */
|
|||
internal void BeginParsingAttributes()
|
|||
{
|
|||
pState.parsingAttributes = true;
|
|||
}
|
|||
/* gets called when we stop parsing attributes */
|
|||
internal void EndParsingAttributes()
|
|||
{
|
|||
pState.parsingAttributes = false;
|
|||
}
|
|||
/*dummy*/
|
|||
internal bool notIsAttributeInitialization()
|
|||
{
|
|||
return !pState.parsingAttributes;
|
|||
}
|
|||
/* create a new(anid) constructor */
|
|||
private Expression createObject(IToken anid)
|
|||
{
|
|||
if (!pState.parsingAttributes)
|
|||
{
|
|||
doError(anid, "Object creation with 'new' only allowed in variable initializers.");
|
|||
return null;
|
|||
}
|
|||
OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
|
|||
pState.typesToFixUp.Add(atype);
|
|||
return new ObjectConstructor(atype, anid.Line, anid.CharPositionInLine);
|
|||
}
|
|||
private Expression createNamedObject(IToken anid, IToken aname)
|
|||
{
|
|||
if (!pState.parsingAttributes)
|
|||
{
|
|||
doError(anid, "Object creation with 'new' only allowed in variable initializers.");
|
|||
return null;
|
|||
}
|
|||
Regex validid = new Regex("\"[_]*[a-zA-Z][a-zA-Z0-9_]*\"");
|
|||
if (!validid.IsMatch(aname.Text))
|
|||
{
|
|||
doError(aname, "Not a valid identifier");
|
|||
return null;
|
|||
}
|
|||
OpaqueType atype = new OpaqueType(new TypeIdentifier(anid, null, GetScope()));
|
|||
pState.typesToFixUp.Add(atype);
|
|||
return new ObjectConstructor(atype, aname.Text, anid.Line, anid.CharPositionInLine);
|
|||
}
|
|||
internal void setQualitativeDerivDec(QValConstructor result)
|
|||
{
|
|||
result.SetDerivation(QValDeriv.Dec);
|
|||
}
|
|||
internal void setQualitativeDerivInc(QValConstructor result)
|
|||
{
|
|||
result.SetDerivation(QValDeriv.Inc);
|
|||
}
|
|||
internal void setQualitativeDerivSteady(QValConstructor result)
|
|||
{
|
|||
result.SetDerivation(QValDeriv.Steady);
|
|||
}
|
|||
internal void setQualitativeDerivDontCare(QValConstructor result)
|
|||
{
|
|||
result.SetDerivation(QValDeriv.DonTCare);
|
|||
}
|
|||
internal void setQualitativeValueRangeInfinity(QValConstructor result, bool p)
|
|||
{
|
|||
throw new NotImplementedException();
|
|||
}
|
|||
internal void setQualitativeValueRange(QValConstructor result, Expression expr2)
|
|||
{
|
|||
result.AddRange(expr2);
|
|||
}
|
|||
internal void setQualitativeValueInfinity(QValConstructor result, bool minus)
|
|||
{
|
|||
throw new NotImplementedException();
|
|||
}
|
|||
internal void setQualitativeValueLandmark(QValConstructor result, Expression expr)
|
|||
{
|
|||
result.SetValue(expr);
|
|||
}
|
|||
internal void setQualitativeValueDontCare(QValConstructor result)
|
|||
{
|
|||
throw new NotImplementedException();
|
|||
}
|
|||
internal QValConstructor createQualitativeValue(IToken aval)
|
|||
{
|
|||
return new QValConstructor(aval.Line, aval.CharPositionInLine);
|
|||
}
|
|||
/* add a local variable to a named action */
|
|||
internal void addLocalVariableToNamedAction(FunctionIdentifier newMethod, IToken id1, UlyssesType t1)
|
|||
{
|
|||
if (t1 == null)
|
|||
{
|
|||
doError(id1, "Variable lacks type");
|
|||
return;
|
|||
}
|
|||
LocalVariableIdentifier lvar = new LocalVariableIdentifier(id1, t1, GetScope());
|
|||
newMethod.AddIdentifier(lvar, null);
|
|||
}
|
|||
/* ====== */
|
|||
/* ====== */
|
|||
public Dictionary<string, string> readableTokens = new Dictionary<string, string>();
|
|||
private void SetUpTokenDictionary()
|
|||
{
|
|||
if (readableTokens.Count > 0)
|
|||
return;
|
|||
readableTokens.Add("<invalid>", "<invalid>");
|
|||
readableTokens.Add("<EOR>", "<EOR>");
|
|||
readableTokens.Add("<DOWN>", "<DOWN>");
|
|||
readableTokens.Add("<UP>", "<UP>");
|
|||
readableTokens.Add("T_TYPES", "'types'");
|
|||
readableTokens.Add("T_SYSTEM", "'system'");
|
|||
readableTokens.Add("T_SEMICOLON", "';'");
|
|||
readableTokens.Add("T_IDENTIFIER", "<identifier>");
|
|||
readableTokens.Add("T_EQUAL", "'='");
|
|||
readableTokens.Add("T_PRIO", "'//'");
|
|||
readableTokens.Add("T_NONDET", "'[]'");
|
|||
readableTokens.Add("T_LPAREN", "'('");
|
|||
readableTokens.Add("T_RPAREN", "')'");
|
|||
readableTokens.Add("T_LIST", "'list'");
|
|||
readableTokens.Add("T_LSQPAREN", "'['");
|
|||
readableTokens.Add("T_INTNUMBER", "<integer>");
|
|||
readableTokens.Add("T_RSQPAREN", "']'");
|
|||
readableTokens.Add("T_OF", "'of'");
|
|||
readableTokens.Add("T_COMMA", "','");
|
|||
readableTokens.Add("T_MAP", "'map'");
|
|||
readableTokens.Add("T_TO", "'to'");
|
|||
readableTokens.Add("T_QUANTITY", "'quantity'");
|
|||
readableTokens.Add("T_INFTY", "'inf'");
|
|||
readableTokens.Add("T_BOOL", "'bool'");
|
|||
readableTokens.Add("T_INT", "'int'");
|
|||
readableTokens.Add("T_RANGETO", "'..'");
|
|||
readableTokens.Add("T_FLOAT", "'float'");
|
|||
readableTokens.Add("T_FLOATNUMBER", "<floating point number>");
|
|||
readableTokens.Add("T_CHAR", "'char'");
|
|||
readableTokens.Add("T_CBRL", "'{'");
|
|||
readableTokens.Add("T_CBRR", "'}'");
|
|||
readableTokens.Add("T_AUTOCONS", "'autocons'");
|
|||
readableTokens.Add("T_VAR", "'var'");
|
|||
readableTokens.Add("T_METHODS", "'methods'");
|
|||
readableTokens.Add("T_ACTIONS", "'actions'");
|
|||
readableTokens.Add("T_DO", "'do'");
|
|||
readableTokens.Add("T_OD", "'od'");
|
|||
readableTokens.Add("T_STATIC", "'static'");
|
|||
readableTokens.Add("T_COLON", "':'");
|
|||
readableTokens.Add("T_END", "'end'");
|
|||
readableTokens.Add("T_CONT", "'cont'");
|
|||
readableTokens.Add("T_CTRL", "'ctr'");
|
|||
readableTokens.Add("T_OBS", "'obs'");
|
|||
readableTokens.Add("T_REQUIRES", "'requires'");
|
|||
readableTokens.Add("T_AND", "'and'");
|
|||
readableTokens.Add("T_ABORT", "'abort'");
|
|||
readableTokens.Add("T_SKIP", "'skip'");
|
|||
readableTokens.Add("T_KILL", "'kill'");
|
|||
readableTokens.Add("T_SELF", "'self'");
|
|||
readableTokens.Add("T_ASSIGNMENT", "':='");
|
|||
readableTokens.Add("T_WITH", "'with'");
|
|||
readableTokens.Add("T_IF", "'if'");
|
|||
readableTokens.Add("T_THEN", "'then'");
|
|||
readableTokens.Add("T_ELSE", "'else'");
|
|||
readableTokens.Add("T_FORALL", "'forall'");
|
|||
readableTokens.Add("T_EXISTS", "'exists'");
|
|||
readableTokens.Add("T_TRUE", "'true'");
|
|||
readableTokens.Add("T_FALSE", "'false'");
|
|||
readableTokens.Add("T_NIL", "'nil'");
|
|||
readableTokens.Add("T_STRINGLITERAL", "'\"<string>\"'");
|
|||
readableTokens.Add("T_NEW", "'new'");
|
|||
readableTokens.Add("T_BAR", "'|'");
|
|||
readableTokens.Add("T_MAPS", "'->'");
|
|||
readableTokens.Add("T_PRIMED", "'''");
|
|||
readableTokens.Add("T_POINT", "'.'");
|
|||
readableTokens.Add("T_NOTEQUAL", "'<>'");
|
|||
readableTokens.Add("T_SEQMOD_MAPOVERRIDE", "'++'");
|
|||
readableTokens.Add("T_BIIMPLIES", "'<=>'");
|
|||
readableTokens.Add("T_IMPLIES", "'=>'");
|
|||
readableTokens.Add("T_OR", "'or'");
|
|||
readableTokens.Add("T_ABS", "'abs'");
|
|||
readableTokens.Add("T_DIV", "'/'");
|
|||
readableTokens.Add("T_GREATER", "'>'");
|
|||
readableTokens.Add("T_GREATEREQUAL", "'>='");
|
|||
readableTokens.Add("T_IDIV", "'div'");
|
|||
readableTokens.Add("T_LESS", "'<'");
|
|||
readableTokens.Add("T_LESSEQUAL", "'<='");
|
|||
readableTokens.Add("T_MINUS", "'-'");
|
|||
readableTokens.Add("T_MOD", "'mod'");
|
|||
readableTokens.Add("T_POW", "'**'");
|
|||
readableTokens.Add("T_PROD", "'*'");
|
|||
readableTokens.Add("T_SUM", "'+'");
|
|||
readableTokens.Add("T_CONC", "'^'");
|
|||
readableTokens.Add("T_DIFF", "'\\'");
|
|||
readableTokens.Add("T_INTER", "'inter'");
|
|||
readableTokens.Add("T_IN", "'in'");
|
|||
readableTokens.Add("T_SET", "'set'");
|
|||
readableTokens.Add("T_NOT", "'not'");
|
|||
readableTokens.Add("T_SUBSET", "'subset'");
|
|||
readableTokens.Add("T_UNION", "'union'");
|
|||
readableTokens.Add("T_DOMRESBY", "'<-:'");
|
|||
readableTokens.Add("T_DOMRESTO", "'<:'");
|
|||
readableTokens.Add("T_RNGRESBY", "':->'");
|
|||
readableTokens.Add("T_RNGRESTO", "':>'");
|
|||
readableTokens.Add("T_MUNION", "'munion'");
|
|||
readableTokens.Add("T_CARD", "'card'");
|
|||
readableTokens.Add("T_DCONC", "'conc'");
|
|||
readableTokens.Add("T_DINTER", "'dinter'");
|
|||
readableTokens.Add("T_DUNION", "'dunion'");
|
|||
readableTokens.Add("T_ELEMS", "'elems'");
|
|||
readableTokens.Add("T_HEAD", "'hd'");
|
|||
readableTokens.Add("T_INDS", "'inds'");
|
|||
readableTokens.Add("T_LEN", "'len'");
|
|||
readableTokens.Add("T_TAIL", "'tl'");
|
|||
readableTokens.Add("T_DOM", "'dom'");
|
|||
readableTokens.Add("T_RNG", "'rng'");
|
|||
readableTokens.Add("T_MERGE", "'merge'");
|
|||
readableTokens.Add("T_WS", "<space>");
|
|||
readableTokens.Add("T_COMMENT", "'/*<comment>*/'");
|
|||
readableTokens.Add("LINE_COMMENT", "'#<line comment>'");
|
|||
readableTokens.Add("T_DIGIT", "<0..9>");
|
|||
readableTokens.Add("FLOAT_OR_INT_OR_RANGE", "<float_int_range>");
|
|||
readableTokens.Add("T_LETTER", "<a..z,A..Z>");
|
|||
readableTokens.Add("'|['", "'|['");
|
|||
readableTokens.Add("']|'", "']|'");
|
|||
readableTokens.Add("'add'", "'add'");
|
|||
readableTokens.Add("'mult'", "'mult'");
|
|||
readableTokens.Add("'deriv'", "'deriv'");
|
|||
readableTokens.Add("'mon+'", "'mon+'");
|
|||
readableTokens.Add("'mon-'", "'mon-'");
|
|||
readableTokens.Add("'id'", "'id'");
|
|||
readableTokens.Add("'qval'", "'qval'");
|
|||
readableTokens.Add("'\"'", "'\"'");
|
|||
readableTokens.Add("as", "as");
|
|||
}
|
|||
/* override routine that displays recongition errors.. */
|
|||
public override void DisplayRecognitionError(String[] tokenNames, RecognitionException e)
|
|||
{
|
|||
int i;
|
|||
System.Text.StringBuilder result = new System.Text.StringBuilder();
|
|||
SetUpTokenDictionary();
|
|||
if (e is MismatchedTokenException)
|
|||
{
|
|||
result.Append("Found '");
|
|||
result.Append(e.Token.Text);
|
|||
result.Append("'");
|
|||
i = ((MismatchedTokenException)e).Expecting;
|
|||
result.Append(" Expected: ");
|
|||
result.Append(readableTokens[tokenNames[i]]);
|
|||
result.Append(" ("); result.Append(tokenNames[i]); result.Append(") ");
|
|||
}
|
|||
else
|
|||
{
|
|||
/*if (e is NoViableAltException)
|
|||
{
|
|||
result.Append("Unexpected '");
|
|||
result.Append(e.Token.Text);
|
|||
result.Append("' (");
|
|||
i = ((NoViableAltException)e).UnexpectedType;
|
|||
result.Append(tokenNames[i]);
|
|||
result.Append(")");
|
|||
}
|
|||
else*/
|
|||
if (e is RecognitionException)
|
|||
{
|
|||
result.Append("Unexpected '");
|
|||
result.Append(e.Token.Text);
|
|||
result.Append("' (");
|
|||
i = ((RecognitionException)e).UnexpectedType;
|
|||
result.Append(tokenNames[i]);
|
|||
result.Append(") ");
|
|||
}
|
|||
else
|
|||
result.Append(e.Message);
|
|||
}
|
|||
pState.AddErrorMessage(new ParserError(pState.filename, e.Line, e.CharPositionInLine, result.ToString()));
|
|||
}
|
|||
/* just run over once */
|
|||
public static int FirstPass(ParserState pState)
|
|||
{
|
|||
pState.parser.ooActionSystems();
|
|||
return pState.listOfParserErrors.Count; // + pState.lexer.NumberOfSyntaxErrors;
|
|||
}
|
|||
/* print syntax tree */
|
|||
public static string PrintSyntaxTree(ParserState pState)
|
|||
{
|
|||
if ((pState != null) && (pState.ooaSystem != null))
|
|||
{
|
|||
return pState.ooaSystem.ToString();
|
|||
}
|
|||
else
|
|||
return String.Empty;
|
|||
}
|
|||
}
|
|||
}
|