private int GetInfixPrecedence(MathTokenType type) { switch (type) { case MathTokenType.BitwiseOr: return((int)Precedences.Or); case MathTokenType.BitwiseXor: return((int)Precedences.Xor); case MathTokenType.BitwiseAnd: return((int)Precedences.And); case MathTokenType.LeftShift: case MathTokenType.RightShift: case MathTokenType.ARightShift: return((int)Precedences.Shifts); case MathTokenType.Plus: case MathTokenType.Minus: return((int)Precedences.Sums); case MathTokenType.Multiply: case MathTokenType.Divide: case MathTokenType.Modulus: return((int)Precedences.Products); default: return((int)Precedences.NoPrecedence); } }
public Token <MathTokenType> Take(MathTokenType type) { var token = Take(); if (token.Identifier != type) { throw new RantException(_src, token, String.Concat("Expression expected ", type, ", but found ", token.Identifier, ".")); } return(token); }
private bool IsPrefixTokenType(MathTokenType type) { switch (type) { case MathTokenType.Identifer: case MathTokenType.IntLiteral: case MathTokenType.LeftParenthesis: case MathTokenType.Plus: case MathTokenType.Minus: return(true); } return(false); }
private IExpression <T> ParsePrecedence(IScanner <Token> scanner, out Match <Token> match, int precedence) { match = new Match <Token> (scanner); MathTokenType tokenType = GetMathTokenType(scanner.Current); if (IsPrefixTokenType(tokenType)) { Match <Token> prefixMatch; IExpression <T> current = ParsePrefix(tokenType, scanner, out prefixMatch); match += prefixMatch; if (!match.Success) { return(null); } tokenType = GetMathTokenType(scanner.Current); while (IsInfixTokenType(tokenType)) { if (precedence >= GetInfixPrecedence(tokenType)) { break; } Match <Token> infixMatch; current = ParseInfix(tokenType, scanner, out infixMatch, current); match += infixMatch; if (!match.Success) { return(null); } tokenType = GetMathTokenType(scanner.Current); } return(current); } match = new Match <Token> (scanner, "couldn't parse math expression"); return(null); }
private IExpression <T> ParseInfix(MathTokenType type, IScanner <Token> scanner, out Match <Token> match, IExpression <T> previous) { match = new Match <Token> (scanner); ++match; scanner.MoveNext(); Match <Token> rightMatch; IExpression <T> right = ParsePrecedence(scanner, out rightMatch, GetInfixPrecedence(type)); match += rightMatch; if (match.Success) { return(MakeBinaryOpExpression(type, previous, right, previous.Position)); } return(null); }
private bool IsInfixTokenType(MathTokenType type) { switch (type) { case MathTokenType.Plus: case MathTokenType.Minus: case MathTokenType.Multiply: case MathTokenType.Divide: case MathTokenType.Modulus: case MathTokenType.BitwiseAnd: case MathTokenType.BitwiseOr: case MathTokenType.BitwiseXor: case MathTokenType.LeftShift: case MathTokenType.RightShift: case MathTokenType.ARightShift: return(true); } return(false); }
private IExpression <T> MakeBinaryOpExpression(MathTokenType type, IExpression <T> left, IExpression <T> right, FilePosition pos) { switch (type) { case MathTokenType.Plus: return(new Sum <T> (left, right, pos)); case MathTokenType.Minus: return(new Minus <T> (left, right, pos)); case MathTokenType.Multiply: return(new Multiply <T> (left, right, pos)); case MathTokenType.Divide: return(new Division <T> (left, right, pos)); case MathTokenType.Modulus: return(new Modulus <T> (left, right, pos)); case MathTokenType.BitwiseOr: return(new BitwiseOr <T> (left, right, pos)); case MathTokenType.BitwiseAnd: return(new BitwiseAnd <T> (left, right, pos)); case MathTokenType.BitwiseXor: return(new BitwiseXor <T> (left, right, pos)); case MathTokenType.LeftShift: return(new BitShiftLeft <T> (left, right, pos)); case MathTokenType.RightShift: return(new BitShiftRight <T> (left, right, pos)); case MathTokenType.ARightShift: return(new ArithmeticShiftRight <T> (left, right, pos)); default: return(null); } }
public MathToken(MathTokenType t, double d) { Type = t; Value = d; Char = char.MinValue; }
public MathToken(MathTokenType type, double value) : this() { this.Type = type; Value = value; }
public MathToken(MathTokenType type, char ch) : this() { this.Type = type; Char = ch; }
public MathExpressionToken(MathTokenType tokenType, Double value) { TokenType = tokenType; Value = value; }
private IExpression <T> ParsePrefix(MathTokenType type, IScanner <Token> scanner, out Match <Token> match) { match = new Match <Token> (scanner); IExpression <T> result = null; switch (type) { case MathTokenType.Identifer: result = new Symbol <T> (scanner.Current.Value, scanner.Current.Position); ++match; scanner.MoveNext(); return(result); case MathTokenType.IntLiteral: try { result = new ValueExpression <T> (evaluate(scanner.Current.Value), scanner.Current.Position); ++match; scanner.MoveNext(); return(result); } catch (Exception) { match = new Match <Token> (scanner, "failed to parse integer literal \"{0}\"", scanner.Current.Value); return(null); } case MathTokenType.LeftParenthesis: { ++match; scanner.MoveNext(); Match <Token> outMatch; result = ParsePrecedence(scanner, out outMatch, (int)Precedences.NoPrecedence); if (scanner.Current.Type != TokenType.RightParenthesis) { match = new Match <Token> (scanner, "couldn't find closing parenthesis"); return(null); } match += outMatch; ++match; scanner.MoveNext(); return(result); } case MathTokenType.Plus: { ++match; scanner.MoveNext(); Match <Token> outMatch; result = ParsePrecedence(scanner, out outMatch, (int)Precedences.Prefixes); match += outMatch; return(result); } case MathTokenType.Minus: { FilePosition pos = scanner.Current.Position; ++match; scanner.MoveNext(); Match <Token> outMatch; result = ParsePrecedence(scanner, out outMatch, (int)Precedences.Prefixes); match += outMatch; return(new Minus <T> (null, result, pos)); } } return(null); }
public MathExpressionToken(MathTokenType tokenType) { TokenType = tokenType; }
public MathExpressionToken(MathTokenType tokenType, char op) { TokenType = tokenType; Operator = op; }
public MathExpressionToken(MathTokenType tokenType, string name) { TokenType = tokenType; Name = name; }
public MathToken(MathTokenType t, double d) { Type = t; Char = '\0'; Value = d; }
public MathToken(MathTokenType t, char c) { Type = t; Char = c; Value = double.NaN; }
public Token<MathTokenType> Take(MathTokenType type) { var token = Take(); if (token.Identifier != type) { throw new ManhoodException(_src, token, String.Concat("Expression expected ", type, ", but found ", token.Identifier, ".")); } return token; }