/// <summary> /// Creates an instance of <see cref="Component"/> /// from the values of children nodes of <see cref="Symbols.Component"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="Component"/>. /// </returns> private SpiceObject CreateComponent(ParseTreeNodeEvaluationValues values) { if (values.Count != 2 && values.Count != 3) { throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); } var component = new Component( values.GetLexem(0), values.GetSpiceObject <ParameterCollection>(1), new SpiceLineInfo(values)); switch ((SpiceTokenType)values.GetToken(0).Type) { case SpiceTokenType.SUFFIX: component.NameParameter = new SuffixParameter(values.GetLexem(0)); break; default: component.NameParameter = new WordParameter(values.GetLexem(0)); break; } return(component); }
private SpiceObject CreatePointParameter(ParseTreeNodeEvaluationValues nt) { var values = nt.GetSpiceObject <PointValues>(1); var pointParameter = new PointParameter(values, new SpiceLineInfo(nt)); return(pointParameter); }
/// <summary> /// Translates a SPICE parse tree to a context. /// </summary> /// <param name="root">A parse tree root.</param> /// <returns>A netlist.</returns> public SpiceObject Evaluate(ParseTreeNode root) { if (root == null) { throw new ArgumentNullException(nameof(root)); } var traversal = new ParseTreeTraversal(); // Get tree nodes in post order var treeNodes = traversal.GetIterativePostOrder(root); // Iterate over tree nodes foreach (var treeNode in treeNodes) { if (treeNode is ParseTreeNonTerminalNode nt) { var items = new ParseTreeNodeEvaluationValues(nt.LineNumber, nt.StartColumnIndex, nt.EndColumnIndex, nt.FileName); foreach (var child in nt.Children) { items.Add(treeNodesValues[child]); } if (!evaluators.ContainsKey(nt.Name)) { throw new ParseTreeEvaluationException("Unsupported evaluation of parse tree node: " + nt.Name); } var treeNodeResult = evaluators[nt.Name](items); treeNodesValues[treeNode] = new ParseTreeNonTerminalEvaluationValue { SpiceObject = treeNodeResult, Node = treeNode, }; } else { treeNodesValues[treeNode] = new ParseTreeNodeTerminalEvaluationValue() { Node = treeNode, Token = ((ParseTreeTerminalNode)treeNode).Token, }; } } if (treeNodesValues[root] is ParseTreeNonTerminalEvaluationValue rootNt) { return(rootNt.SpiceObject); } else { return(null); } }
/// <summary> /// Returns new instance of <see cref="ParameterCollection"/> /// from the values of children nodes of <see cref="Symbols.Parameters"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="ParameterCollection"/>. /// </returns> private SpiceObject CreateParameters(ParseTreeNodeEvaluationValues values) { var parameters = new ParameterCollection(); if (values.Count == 3) { parameters.Add(values.GetSpiceObject <Parameter>(0)); parameters.Merge(values.GetSpiceObject <ParameterCollection>(2)); } return(parameters); }
/// <summary> /// Creates an instance of <see cref="Component"/> /// from the values of children nodes of <see cref="Symbols.Component"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="Component"/>. /// </returns> private SpiceObject CreateComponent(ParseTreeNodeEvaluationValues values) { if (values.Count != 2 && values.Count != 3) { throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); } var component = new Component( values.GetLexem(0), values.GetSpiceObject <ParameterCollection>(1), new SpiceLineInfo(values)); return(component); }
/// <summary> /// Returns new instance of <see cref="Control"/> /// from the values of children nodes of <see cref="Symbols.Control"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="Control"/>. /// </returns> private SpiceObject CreateControl(ParseTreeNodeEvaluationValues values) { Control control; SpiceLineInfo lineInfo = new SpiceLineInfo(values); switch (values.GetLexem(0).ToLower()) { case ".endl": control = new Control("endl", new ParameterCollection(), lineInfo); break; case ".if": control = new Control( "if", new ParameterCollection( new List <Parameter>() { new ExpressionParameter(values.GetLexem(1), lineInfo), }), lineInfo); break; case ".elseif": control = new Control( "elseif", new ParameterCollection( new List <Parameter>() { new ExpressionParameter(values.GetLexem(1), lineInfo), }), lineInfo); break; case ".else": control = new Control("else", new ParameterCollection(new List <Parameter>()), lineInfo); break; case ".endif": control = new Control("endif", new ParameterCollection(new List <Parameter>()), lineInfo); break; default: control = new Control(values.GetLexem(1), values.GetSpiceObject <ParameterCollection>(2), lineInfo); break; } return(control); }
/// <summary> /// Returns new instance of <see cref="ReferenceParameter"/> /// or <see cref="ValueParameter"/> or <see cref="WordParameter"/> /// or <see cref="ExpressionParameter"/> or <see cref="IdentifierParameter"/> /// from the values of children nodes of <see cref="Symbols.ParameterSingle"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SingleParameter"/>. /// </returns> private SpiceObject CreateParameterSingle(ParseTreeNodeEvaluationValues values) { if (values[0] is ParseTreeNodeTerminalEvaluationValue t) { var lexemValue = t.Token.Lexem; switch (t.Token.SpiceTokenType) { case SpiceTokenType.REFERENCE: return(new ReferenceParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.DOUBLE_QUOTED_STRING: return(new StringParameter(lexemValue.Trim('"'), new SpiceLineInfo(t.Token))); case SpiceTokenType.SINGLE_QUOTED_STRING: return(new StringParameter(lexemValue.Trim('\''), new SpiceLineInfo(t.Token))); case SpiceTokenType.VALUE: return(new ValueParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.WORD: return(new WordParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.SUFFIX: return(new SuffixParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.PREFIX_SINGLE: case SpiceTokenType.PREFIX_COMPLEX: return(new PrefixParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.IDENTIFIER: return(new IdentifierParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.EXPRESSION: return(new ExpressionParameter(lexemValue, new SpiceLineInfo(t.Token))); case SpiceTokenType.EXPRESSION_BRACKET: return(new ExpressionParameter(lexemValue.Replace("}", string.Empty).Replace("{", string.Empty), new SpiceLineInfo(t.Token))); case SpiceTokenType.EXPRESSION_SINGLE_QUOTES: return(new ExpressionParameter(lexemValue.Trim('\''), new SpiceLineInfo(t.Token))); case SpiceTokenType.PERCENT: return(new PercentParameter(lexemValue.TrimEnd('%'), new SpiceLineInfo(t.Token))); } } throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); }
/// <summary> /// Returns new instance of <see cref="SpiceNetlist"/> /// from the values of children nodes of <see cref="Symbols.Netlist"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SpiceNetlist"/>. /// </returns> private SpiceObject CreateNetlist(ParseTreeNodeEvaluationValues values) { if (values.Count == 3) { return(new SpiceNetlist(string.Empty, values.GetSpiceObject <Statements>(1))); } else { if (values.Count == 1) { return(new SpiceNetlist(null, new Statements())); } return(new SpiceNetlist(values.GetLexem(0), values.Count >= 3 ? values.GetSpiceObject <Statements>(2) : new Statements())); } }
private SpiceObject CreatePoints(ParseTreeNodeEvaluationValues values) { var points = new Points(); if (values.Count == 2) { points.Values.Add(values.GetSpiceObject <PointParameter>(0)); points.Values.AddRange(values.GetSpiceObject <Points>(1).Values); } if (values.Count == 4) { points.Values.Add(values.GetSpiceObject <PointParameter>(1)); points.Values.AddRange(values.GetSpiceObject <Points>(2).Values); } return(points); }
/// <summary> /// Returns new instance of <see cref="SubCircuit"/> /// from the values of children nodes of <see cref="Symbols.Subckt"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SubCircuit"/>. /// </returns> private SpiceObject CreateSubCircuit(ParseTreeNodeEvaluationValues values) { if (values.Count < 3) { throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); } var subCkt = new SubCircuit(values.GetLexem(2), new Statements(), new ParameterCollection(), new SpiceLineInfo(values)); var allParameters = values.GetSpiceObject <ParameterCollection>(3); // Parse nodes and parameters bool mode = true; // true = nodes, false = parameters foreach (var parameter in allParameters) { if (mode) { // After this, only parameters will follow if (parameter is SingleParameter s && s.Image.ToLower() == "params:") { mode = false; } // Parameters have started, so we will keep reading parameters else if (parameter is AssignmentParameter a) { mode = false; subCkt.DefaultParameters.Add(a); } // Still reading nodes else if (parameter is SingleParameter s2) { if (s2 is WordParameter || s2 is IdentifierParameter || s2 is PrefixParameter || s2 is SuffixParameter || int.TryParse(s2.Image, out _)) { subCkt.Pins.Add(s2); } } }
/// <summary> /// Returns new instance of <see cref="SingleParameter"/> /// or <see cref="BracketParameter"/> /// or <see cref="AssignmentParameter"/> /// or <see cref="VectorParameter"/> /// from the values of children nodes of <see cref="Symbols.Parameter"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SingleParameter"/>. /// </returns> private SpiceObject CreateParameter(ParseTreeNodeEvaluationValues values) { if (values.Count == 1) { if (values.TryToGetSpiceObject(0, out VectorParameter vp)) { return(vp); } if (values.TryToGetSpiceObject(0, out SingleParameter sp)) { return(sp); } if (values.TryToGetSpiceObject(0, out BracketParameter bp)) { return(bp); } if (values.TryToGetSpiceObject(0, out AssignmentParameter ap)) { return(ap); } if (values.TryToGetSpiceObject(0, out ExpressionEqualParameter eep)) { return(eep); } if (values.TryToGetSpiceObject(0, out PointParameter pp)) { return(pp); } } throw new ParseTreeEvaluationException("Error during translating parse tree to Spice Object Model"); }
private SpiceObject CreatePointValues(ParseTreeNodeEvaluationValues values) { var pointValues = new PointValues(new SpiceLineInfo(values)); if (values.Count == 3) { pointValues.Items.Add(values.GetSpiceObject <SingleParameter>(0)); pointValues.Items.AddRange(values.GetSpiceObject <PointValues>(2).Items); } else { if (values.Count == 2) { pointValues.Items.Add(values.GetSpiceObject <SingleParameter>(0)); pointValues.Items.AddRange(values.GetSpiceObject <PointValues>(1).Items); } else { pointValues.Items.Add(values.GetSpiceObject <SingleParameter>(0)); } } return(pointValues); }
/// <summary> /// Returns new instance of <see cref="SpiceNetlist"/> /// from the values of children nodes of <see cref="Symbols.Netlist"/> parse tree node. /// </summary> /// <returns> /// A new instance of <see cref="SpiceNetlist"/>. /// </returns> private SpiceObject CreateNetlistWithoutTitle(ParseTreeNodeEvaluationValues values) { return(new SpiceNetlist(null, values.GetSpiceObject <Statements>(0))); }
private SpiceObject CreatePointValue(ParseTreeNodeEvaluationValues nt) { return((nt[0] as ParseTreeNonTerminalEvaluationValue)?.SpiceObject); }