/** * * 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 listOfParserErrors; public List listOfParserWarnings; public List listOfParserMessages; public List typesToFixUp; public ParserState(Program.Options options) { listOfParserErrors = new List(); listOfParserWarnings = new List(); listOfParserMessages = new List(); typesToFixUp = new List(); 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 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 expressions, List 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 expressions, List 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)((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)((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)((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)((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)((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)((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(), 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(), 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 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 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(p, token.Line, token.CharPositionInLine); } /* create a nil */ internal LeafExpression createNullPointerConstant() { IToken token = input.LT(-1); return new ValueExpression(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.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.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(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 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: ().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 readableTokens = new Dictionary(); private void SetUpTokenDictionary() { if (readableTokens.Count > 0) return; readableTokens.Add("", ""); readableTokens.Add("", ""); readableTokens.Add("", ""); readableTokens.Add("", ""); readableTokens.Add("T_TYPES", "'types'"); readableTokens.Add("T_SYSTEM", "'system'"); readableTokens.Add("T_SEMICOLON", "';'"); readableTokens.Add("T_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", ""); 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", ""); 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", "'\"\"'"); 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", ""); readableTokens.Add("T_COMMENT", "'/**/'"); readableTokens.Add("LINE_COMMENT", "'#'"); readableTokens.Add("T_DIGIT", "<0..9>"); readableTokens.Add("FLOAT_OR_INT_OR_RANGE", ""); readableTokens.Add("T_LETTER", ""); 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; } } }