private Rule parseUpdateRule(string pname, string rule, Declarations decls) { int len = 1; int equal = rule.IndexOf(":="); if (equal < 0) { equal = rule.IndexOf('='); } else { len = 2; } if (equal < 0) { throw new ParseException(String.Format("Invalid update rule '{0}'!", rule)); } string varname = rule.Substring(0, equal).Trim(); string upexpr = rule.Substring(equal + len).Trim(); VarDecl vd = decls.getVar(varname); if (vd == null) { throw new ParseException(String.Format("Unknown variable {0}!", varname)); } string expr = String.Format("int _UPDATE_{0} = {1};", varname, upexpr); Declarations newdecls = parseDeclarations(expr, decls); Expression e = newdecls.getFirstDecl().Expr; return(new UpdateRule(varname, e)); }
private Rule parseSyncRule(string pname, string rule, Declarations decls) { SyncRule.Direction dir; if (rule.EndsWith("?")) { dir = SyncRule.Direction.Receive; } else if (rule.EndsWith("!")) { dir = SyncRule.Direction.Send; } else { throw new ParseException(String.Format("Synchronization rule '{0}' must end with '!' or '?'!")); } rule = rule.TrimEnd(new char[] { '?', '!' }); string expr = String.Format("chan _CHANNEL_ = {0};", rule); Declarations newdecls = parseDeclarations(expr, decls); Expression e = newdecls.getVar("_CHANNEL_").Expr; return(new SyncRule(e, dir)); }
private void markUnreferenced(Declarations d) { foreach (VarDecl vd in d.getAllVars()) { vd.Referenced = false; } }
public TypeDecl GetType(Declarations symtab) { switch (Type) { case ExpType.Const: return(new TypeDecl() { Type = VarType.Int }); case ExpType.Var: VarDecl v = symtab.getVar(Var); if (v == null) { throw new ParseException(String.Format("Unknown variable {0}", Var)); } return(v.Type); case ExpType.Func: // this should be improved later return(new TypeDecl() { Type = VarType.Int }); default: throw new ParseException("Internal error 1"); } }
private void markReferences(Declarations d, Expression e) { switch (e.Type) { case Expression.ExpType.Const: return; case Expression.ExpType.Var: markReferencesForVar(d, e.Var); return; case Expression.ExpType.Func: if (e.First != null) { markReferences(d, e.First); } if (e.Second != null) { markReferences(d, e.Second); } if (e.Third != null) { markReferences(d, e.Third); } return; } }
public void fold(Declarations symtab) { switch (Type) { case ExpType.ConstInt: break; case ExpType.ConstBool: break; case ExpType.Var: int val = 0; if (symtab.getVarValue(Var, out val)) { Value = val; Type = ExpType.ConstInt; } break; case ExpType.Func: while (foldFunc(symtab)) { } break; } }
private Model run(string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); XmlNode declsnode = doc.SelectSingleNode("/nta/declaration"); Declarations decls = new Declarations(); if (declsnode != null && getElementText(declsnode) != null) { decls = parseDeclarations(getElementText(declsnode), null); } XmlNodeList templates = doc.SelectNodes("/nta/template"); if (templates == null) { throw new ParseException("No templates found!"); } Template[] tmpllist = (from XmlNode node in templates select parseTemplate((XmlElement)node, decls)).Where(n => n != null).ToArray(); return(new Model(decls, tmpllist)); }
private StateNode parseNode(XmlElement node, Declarations decls) { Console.WriteLine(" Parsing node ..."); string id = node.GetAttribute("id"); if (id == null) { throw new ParseException("Expected id in <location>"); } XmlNode namenode = node.SelectSingleNode("./name"); string name = string.IsNullOrEmpty(getElementText(namenode)) ? String.Format("Unnamed{0}", _noname++) : getElementText(namenode); NodeMode mode = NodeMode.Regular; if (node.SelectSingleNode("./commited") != null) { mode = NodeMode.Commited; } else if (node.SelectSingleNode("./urgent") != null) { mode = NodeMode.Commited; } StateNode sn = new StateNode(name, id, mode); sn.Rules = parseRules(node, sn.Name, decls); return(sn); }
// add paramters later public Template(string name, Declarations declarations, StateNode initial, StateNode[] nodes, StateTransition[] transitions) { Name = name; Declarations = declarations; Initial = initial; Nodes = nodes; Transitions = transitions; }
private Rule parseGuardRule(string pname, string rule, Declarations decls) { string expr = String.Format("bool _GUARD_ = {0};", rule); Declarations newdecls = parseDeclarations(expr, decls); Expression e = newdecls.getVar("_GUARD_").Expr; return(new GuardRule(e)); }
private void FormatDeclarationsInitialization(Declarations decl) { foreach (VarDecl vd in decl.getVarsByType(VarType.Clock)) { FormatSingleVarInitialization(vd, decl); } foreach (VarDecl vd in decl.getVarsByType(VarType.Int)) { FormatSingleVarInitialization(vd, decl); } }
private void discardUnreferenced(Declarations d) { VarDecl[] vds = d.getAllVars().ToArray(); foreach (VarDecl vd in vds) { if (!vd.Referenced) { d.removeVar(vd); } } }
private void FormatDeclarations(string prefix, Declarations decl) { foreach (VarDecl vd in decl.getVarsByType(VarType.Clock)) { FormatSingleVarDeclaration("clk", prefix, vd); } foreach (VarDecl vd in decl.getVarsByType(VarType.Int)) { FormatSingleVarDeclaration("int", prefix, vd); } }
private Declarations parseDeclarations(string s, Declarations parent) { Console.WriteLine(" Parsing declarations ..."); Scanner scanner = new Scanner(genStreamFromString(s)); Parser parser = new Parser(scanner); parser.decls.Parent = parent; parser.Parse(); if (parser.errors.count > 0) { throw new ParseException(String.Format("{0} error(s).", parser.errors.count)); } return(parser.decls); }
private void FormatTemplateChannelList(Declarations d) { foreach (var v in d.getVarsByType(VarType.Channel)) { if (v.IsArray) { for (int i = 0; i < v.ArrLength; ++i) { app(" &{0}_{1},", getUniqueName(v), i); } } else { app(" &{0},", getUniqueName(v)); } } }
private Rule[] parseRules(XmlElement node, string pname, Declarations decls) { Console.WriteLine(" Parsing rules ..."); XmlNodeList nodes = node.SelectNodes("./label"); List <Rule> rules = new List <Rule>(); foreach (XmlNode subnode in nodes) { XmlElement elem = (XmlElement)subnode; string kind = elem.GetAttribute("kind"); string values_str = getElementText(elem); switch (kind) { case "comments": break; case "synchronisation": rules.Add(parseSyncRule(pname, values_str.Trim(), decls)); break; case "invariant": rules.Add(parseGuardRule(pname, values_str.Trim(), decls)); break; case "guard": rules.Add(parseGuardRule(pname, values_str.Trim(), decls)); break; case "assignment": string[] values = values_str.Split(new char[] { ',' }); rules.AddRange(values.Select(value => parseUpdateRule(pname, value.Trim(), decls))); break; case "select": Console.WriteLine("WARNING: transaction select not yet supported!"); throw new SelectNotSupportException(); //throw new ParseException("transaction select not yet supported!"); //break; default: throw new ParseException(String.Format("label of kind {0} not supported!", kind)); } } return(rules.ToArray()); }
private void FormatSingleVarInitialization(VarDecl vd, Declarations decl) { string name = getUniqueName(vd); if (!vd.HasExpr) { return; } int val; if (!decl.getExprValue(vd.Expr, out val)) { throw new Exception(String.Format("Cannot use non const variable!")); } app(" {0}({1}),", name, val); }
static bool getFoldedBoolValue(Expression e, Declarations symtab, out bool val) { val = false; if (e == null) { return(false); } e.fold(symtab); if (e.Type != ExpType.ConstBool) { return(false); } val = e.Value != 0; return(true); }
static bool getFoldedValue(Expression e, Declarations symtab, out int val) { val = 0; if (e == null) { return(false); } e.fold(symtab); if (e.Type != ExpType.Const) { return(false); } val = e.Value; return(true); }
private string FormatGuardFunction(string objname, Declarations decls, IEnumerable <Rule> rules) { GuardRule guard = (GuardRule)rules.SingleOrDefault(x => x is GuardRule); if (guard == null) { return(NULL); } string funcname = String.Format("guardfunc_{0}", objname); ExpressionGenerator eg = new ExpressionGenerator(getUniqueName, decls, StateStructName); app("static bool {0}()", funcname); app("{{"); app(" {0}", eg.generate(guard)); app("}};"); return(funcname); }
private void markReferencesForVar(Declarations d, string var) { var data = d.getVarWithScope(var); if (data == null) { throw new Exception(String.Format("Could not find variable: {0}", var)); } if (data.var.Referenced) { return; } data.var.Referenced = true; if (data.var.HasExpr) { markReferences(data.decl, data.var.Expr); } }
private string FormatUpdateFunction(string objname, Declarations decls, IEnumerable <Rule> rules) { UpdateRule[] urules = (rules.Where(x => x is UpdateRule).Select(x => (UpdateRule)x).ToArray()); if (urules == null || urules.Length == 0) { return(NULL); } string funcname = String.Format("updatefunc_{0}", objname); ExpressionGenerator eg = new ExpressionGenerator(getUniqueName, decls, StateStructName); app("static void {0}()", funcname); app("{{"); foreach (UpdateRule ur in urules) { app(" {0}", eg.generate(ur)); } app("}};"); return(funcname); }
public ExpressionGenerator(GetNameDelegate namer, Declarations decls, string stateStructName) { _stateStructName = stateStructName; _decls = decls; _namer = namer; }
private ChannelPriority(Declarations d) { _decls = d; }
private Template parseTemplate(XmlElement node, Declarations globaldecls) { try { Console.WriteLine(" Parsing template ..."); TemplateState state = new TemplateState(); XmlNodeList subnodes; XmlNode namenode = node.SelectSingleNode("./name"); if (namenode == null || string.IsNullOrEmpty(getElementText(namenode))) { throw new ParseException("No name node!"); } state._name = getElementText(namenode); if (_templates.Count > 0 && !_templates.Contains(state._name)) { return(null); } XmlNode decnode = node.SelectSingleNode("./declaration"); if (decnode != null) { state._declarations = parseDeclarations(getElementText(decnode), globaldecls); } else { state._declarations = new Declarations() { Parent = globaldecls } }; Console.WriteLine(" Name: " + state._name); subnodes = node.SelectNodes("./location"); if (subnodes != null) { foreach (XmlNode subnode in subnodes) { StateNode sn = parseNode((XmlElement)subnode, state._declarations); state._nodes.Add(sn); } } subnodes = node.SelectNodes("./transition"); if (subnodes != null) { foreach (XmlNode subnode in subnodes) { StateTransition st = parseTransition((XmlElement)subnode, state); state._transitions.Add(st); } } XmlNode initnode = node.SelectSingleNode("./init"); if (initnode == null || string.IsNullOrEmpty(((XmlElement)initnode).GetAttribute("ref"))) { throw new ParseException("No init node!"); } state._init = findNode(((XmlElement)initnode).GetAttribute("ref"), state); if (state._init == null) { throw new ParseException("Init node not found"); } XmlNode parameter = node.SelectSingleNode("./parameter"); if (parameter != null) { throw new ParseException("template parameters not yet supported, easy to add if needed!"); } return(new Template(state._name, state._declarations, state._init, state._nodes.ToArray(), state._transitions.ToArray())); } catch (SelectNotSupportException) { return(null); // for now } }
private bool foldFunc(Declarations symtab) { bool gotfirst, gotsecond; int first, second, third; switch (Func) { case Funcs.BinPlus: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first + second; return(false); } if (gotfirst && first == 0) { copyFrom(Second); return(false); } if (gotsecond && second == 0) { copyFrom(First); return(false); } break; case Funcs.BinMinus: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first - second; return(false); } if (gotsecond && second == 0) { copyFrom(First); return(false); } break; case Funcs.UniPlus: copyFrom(First); return(false); case Funcs.UniMinus: gotfirst = getFoldedValue(First, symtab, out first); if (gotfirst) { Type = ExpType.Const; Value = -first; return(false); } if (First.Type == ExpType.Func && First.Func == Funcs.UniMinus) { copyFrom(First.First); return(false); } break; case Funcs.UniPlusPlusPre: break; case Funcs.UniMinusMinusPre: break; case Funcs.UniPlusPlusPost: break; case Funcs.UniMinusMinusPost: break; case Funcs.Multi: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first * second; return(false); } if (gotfirst && first == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotsecond && second == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotfirst && first == 1) { copyFrom(Second); return(false); } if (gotsecond && second == 1) { copyFrom(First); return(false); } if (first == -1) { First = Second; Second = null; Func = Funcs.UniMinus; return(true); } if (second == -1) { Second = null; Func = Funcs.UniMinus; return(true); } break; case Funcs.Divide: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first / second; return(false); } if (gotfirst && first == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotsecond && second == 0) { throw new ParseException("Divide by Zero!"); } if (gotsecond && second == 1) { copyFrom(First); return(false); } if (first == -1) { First = Second; Second = null; Func = Funcs.UniMinus; return(true); } if (second == -1) { Second = null; Func = Funcs.UniMinus; return(true); } break; case Funcs.Modulus: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first % second; return(false); } if (gotfirst && first == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotsecond && second == 0) { throw new ParseException("Divide by Zero!"); } if (gotsecond && second == 1) { Type = ExpType.Const; Value = 0; return(false); } break; case Funcs.Max: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first > second) ? first : second; return(false); } break; case Funcs.Min: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first > second) ? second : first; return(false); } break; case Funcs.LeftBitShift: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first << second; return(false); } if (gotsecond && second == 0) { copyFrom(Second); return(false); } break; case Funcs.RightBitShift: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first >> second; return(false); } if (gotsecond && second == 0) { copyFrom(Second); return(false); } break; case Funcs.BitAnd: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first & second; return(false); } if (gotfirst && first == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotsecond && second == 0) { Type = ExpType.Const; Value = 0; return(false); } break; case Funcs.BitOr: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first | second; return(false); } if (gotfirst && first == 0) { copyFrom(Second); return(false); } if (gotsecond && second == 0) { copyFrom(First); return(false); } break; case Funcs.BitXor: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = first ^ second; return(false); } break; case Funcs.Larger: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first > second) ? 1 : 0; return(false); } break; case Funcs.LargerEqual: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first >= second) ? 1 : 0; return(false); } break; case Funcs.Smaller: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first < second) ? 1 : 0; return(false); } break; case Funcs.SmallEqual: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first <= second) ? 1 : 0; return(false); } break; case Funcs.Equal: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first == second) ? 1 : 0; return(false); } break; case Funcs.NotEqual: gotfirst = getFoldedValue(First, symtab, out first); gotsecond = getFoldedValue(Second, symtab, out second); if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first != second) ? 1 : 0; return(false); } break; case Funcs.LogicalNot: gotfirst = getFoldedValue(First, symtab, out first); if (gotfirst) { Type = ExpType.Const; Value = (first != 0) ? 0 : 1; return(false); } break; case Funcs.LogicalAnd: gotfirst = getFoldedValue(First, symtab, out first); if (gotfirst && first == 0) { Type = ExpType.Const; Value = 0; return(false); } gotsecond = getFoldedValue(Second, symtab, out second); if (gotsecond && second == 0) { Type = ExpType.Const; Value = 0; return(false); } if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first != 0 && second != 0) ? 1 : 0; return(false); } break; case Funcs.LogicalOr: gotfirst = getFoldedValue(First, symtab, out first); if (gotfirst && first == 1) { Type = ExpType.Const; Value = 1; return(false); } gotsecond = getFoldedValue(Second, symtab, out second); if (gotsecond && second == 1) { Type = ExpType.Const; Value = 1; return(false); } if (gotfirst && gotsecond) { Type = ExpType.Const; Value = (first != 0 || second != 0) ? 1 : 0; return(false); } break; case Funcs.IfThenElse: gotfirst = getFoldedValue(First, symtab, out first); if (gotfirst) { if (first != 0) { copyFrom(Second); } else { copyFrom(Third); } return(false); } getFoldedValue(Second, symtab, out second); getFoldedValue(Third, symtab, out third); return(false); case Funcs.ArrayIndex: if (First == null || Second == null) { throw new ParseException("Array indexer applied to null or is null!"); } First.fold(symtab); if (First.Type != ExpType.Var) { throw new ParseException("Array indexer applied to something that is not a var!"); } First.fold(symtab); Second.fold(symtab); /* add init support later, if needed */ return(false); } return(false); }
public static IEnumerable <StateTransition> getSortedTransitions(Declarations d, IEnumerable <StateTransition> ts) { StateTransition[] transitions = ts.ToArray(); Array.Sort(transitions, (new ChannelPriority(d)).compareByChannelPriority); return(transitions); }
public Declarations(Declarations parent = null) { Parent = parent; }
public Model(Declarations decls, Template[] templates) { Declarations = decls; Templates = templates; }