public static ProcessResult <TreeToken> CreateSyntaxTree(Token[] tokens) { var rootToken = new TreeToken(TokenType.Root, "", 0); var insertionPoint = rootToken; for (var i = 0; i < tokens.Length; i++) { // if a left parenthesis is encountered, we create a new nested token and move the insertion point inside it if (tokens[i].Type == TokenType.LeftParen) { var treeToken = new TreeToken(TokenType.Nested, "()", tokens[i].Position).SetParent(insertionPoint); insertionPoint.Children.Add(treeToken); insertionPoint = treeToken; continue; } // if we encounter a right parenthesis... if (tokens[i].Type == TokenType.RightParen) { // ...we move up to the nearest left paren (or root as a sanity check) while (insertionPoint.Type != TokenType.Nested && insertionPoint.Type != TokenType.Root) { insertionPoint = insertionPoint.Parent; } // ...and then out of it insertionPoint = insertionPoint.Parent; continue; } if (tokens[i].IsCommand && insertionPoint.Type != TokenType.Root && insertionPoint.Type != TokenType.Nested) { insertionPoint = insertionPoint.Parent; } // if the token following a command is not another command, we assume command params and move insertion pointer accordingly if (i > 0 && tokens[i - 1].IsCommand && !tokens[i].IsCommand) { insertionPoint = insertionPoint.Children[^ 1];
/// <summary> /// Verify the current token is a required value, otherwise throw a good exception. /// </summary> /// <param name="reader">ITreeReader to check</param> /// <param name="expected">Current TreeToken expected</param> public static void Expect(this ITreeReader reader, TreeToken expected) { if (reader.TokenType != expected) { throw new IOException($"{reader.GetType().Name} expected \"{expected}\" but found \"{reader.TokenType}\" at {reader.Position:n0}"); } }
public Token(TreeToken treeToken) { Clip = treeToken.Clip; Type = treeToken.Type; Value = treeToken.Value; Position = treeToken.Position; }
public static void WriteLong(this BinaryWriter writer, TreeToken token, long value) { if (value < 0 || value > uint.MaxValue) { // Hint 15: 8 byte value writer.WriteMarker(token, 15); writer.Write(value); } else if (value > ushort.MaxValue) { // Hint 14: 4 byte value writer.WriteMarker(token, 14); writer.Write((uint)value); } else if (value > byte.MaxValue) { // Hint 13: 2 byte value writer.WriteMarker(token, 13); writer.Write((ushort)value); } else if (value > 11) { // Hint 12: 1 byte value writer.WriteMarker(token, 12); writer.Write((byte)value); } else { // Hint 0-11 is value writer.WriteMarker(token, (int)value); } }
public static void WriteMarker(this BinaryWriter writer, TreeToken token, int hint) { if (hint < 0 || hint > 15) { throw new ArgumentException(nameof(hint)); } writer.Write((byte)((byte)(token) + (byte)(hint << 4))); }
public static Func <double, double> CreateDelegate(TreeToken token, string variable, Parser parser, EvaluationOptions options) { var paramColl = new ParameterCollection <double>(variable); var context = new EvaluationContext(options, paramColl); var eval = new ExpressionTreeEvaluator(parser, context); var expr = token.Evaluate(eval); var parameters = paramColl.GetParameters(); return(Expression.Lambda <Func <double, double> >(expr, parameters).Compile()); }
private string evalOperatorSubToken(int precedence, TreeToken subToken) { bool brackets = precedence > OperatorProperties.GetPrecedence(subToken); string expr = subToken.Evaluate(this); if (brackets) { expr = $"{ParserSymbols.LBracket}{expr}{ParserSymbols.RBracket}"; } return(expr); }
public bool Read() { if (_wasBlockArrayRead == false && TokenType == TreeToken.BlockArray) { _reader.SkipBlockArray(_hint); _wasBlockArrayRead = true; } if (_reader.BaseStream.Position == _reader.BaseStream.Length) { TokenType = TreeToken.None; return(false); } byte marker = _reader.ReadByte(); _hint = (byte)(marker >> 4); TokenType = (TreeToken)(marker & 15); switch (TokenType) { case TreeToken.Boolean: _valueBool = (_hint != 0); break; case TreeToken.Integer: _valueLong = _reader.ReadLong(_hint); break; case TreeToken.Float: _valueDouble = _reader.ReadDouble(); break; case TreeToken.String: case TreeToken.PropertyName: _valueString = _reader.ReadString(_hint, ref Settings.Buffer); break; case TreeToken.Null: _valueString = null; break; case TreeToken.BlockArray: _wasBlockArrayRead = false; break; default: // Nothing to read or not pre-read break; } return(true); }
private string evalSub(StructToken token, int subIndex) { TreeToken subToken = token.SubTokens[subIndex]; int precedence = OperatorProperties.GetPrecedence(token); bool brackets = precedence > OperatorProperties.GetPrecedence(subToken); string expr = subToken.Evaluate(this); if (brackets) { expr = $"<mo>(</mo>{expr}<mo>)</mo>"; } return(expr); }
/// <summary> /// Parses a mathematical expression. /// </summary> /// <param name="input">The expression string to be parsed.</param> /// <returns>The result of the parsing as an instance of ParserResult.</returns> public ParserResult Parse(string input) { if (String.IsNullOrWhiteSpace(input)) { return(new ParserResult(this, new NumberToken("0", 0))); } //Read var tokenList = Tokenizer.Read(new InputStream(input)); // Build tree TreeToken treeToken = ParseTree.CreateTree(tokenList); return(new ParserResult(this, treeToken)); }
private static ProcessResult <Token[]> ResolveAndFlattenSyntaxTree(TreeToken syntaxTree) { var flattenedTokens = new List <Token>(); while (!syntaxTree.Children.All(x => x.AllValuesFetched)) { foreach (var treeToken in syntaxTree.Children) { var res = treeToken.FlattenedValues; if (res.Success) { flattenedTokens.AddRange(res.Result); } else { return(res); } } } return(new ProcessResult <Token[]>(flattenedTokens.ToArray())); }
private Expression iterateExpr(double init, TreeToken start, TreeToken end, Expression <Func <double, double, double> > funcExpr) { var iteratorExpr = Expression.Parameter(typeof(double)); var resultExpr = Expression.Parameter(typeof(double)); var returnLabel = Expression.Label(typeof(double)); return(Expression.Block( new[] { iteratorExpr, resultExpr }, Expression.Assign(resultExpr, Expression.Constant(init)), Expression.Assign(iteratorExpr, eval(start)), Expression.Loop( Expression.IfThenElse( Expression.GreaterThan(iteratorExpr, eval(end)), Expression.Return(returnLabel, resultExpr), Expression.Assign(resultExpr, Expression.Invoke(funcExpr, resultExpr, Expression.PostIncrementAssign(iteratorExpr)) ) ), returnLabel ) )); }
public static void WriteString(this BinaryWriter writer, TreeToken token, string value, ref byte[] buffer) { if (string.IsNullOrEmpty(value)) { writer.WriteMarker(token, 0); } else { // Ensure buffer long enough int maxByteLength = 3 * value.Length; if (buffer == null || buffer.Length < maxByteLength) { buffer = new byte[maxByteLength]; } // Convert to UTF-8 int actualByteLength = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, 0); // Write marker and length, then bytes writer.WriteLong(token, actualByteLength); writer.Write(buffer, 0, actualByteLength); } }
private double eval(TreeToken token) => token.Evaluate(this);
private Expression eval(TreeToken token) => token.Evaluate(this);
internal ParserResult(Parser parser, TreeToken treeToken) { this.parser = parser; this.treeToken = treeToken; }
private BigDecimal eval(TreeToken token) => token.Evaluate(this);