コード例 #1
0
 /// <summary>
 /// Constructor for tokens that are not parsed.
 /// </summary>
 /// <param name="text"></param>
 /// <param name="type"></param>
 /// <param name="priority"></param>
 public Token(string text, TokenType type, TokenPriority priority)
 {
     _Text         = text;
     _Type         = type;
     _Priority     = priority;
     _ParsedObject = text;
 }
コード例 #2
0
 /// <summary>
 /// Constructor for tokens that are parsed.
 /// </summary>
 /// <param name="parsedObj"></param>
 /// <param name="type"></param>
 /// <param name="priority"></param>
 public Token(object parsedObj, TokenType type, TokenPriority priority)
 {
     _ParsedObject = parsedObj;
     _Text         = ParsedObject.ToString();
     _Type         = type;
     _Priority     = priority;
 }
コード例 #3
0
ファイル: Parser.cs プロジェクト: hdgardner/ECF
        /// <summary>
        /// Recursive method that reads an expression.
        /// </summary>
        /// <param name="t"></param>
        /// <param name="priority"></param>
        /// <returns></returns>
        private CodeExpression ReadExpression(Tokenizer t, TokenPriority priority)
        {
            CodeExpression left = null, right = null;
            bool           cont = true, applyNot = false, applyNegative = false;

            while (cont)
            {
                switch (t.Current.Type)
                {
                case TokenType.Primitive:
                    left = new CodePrimitiveExpression(t.Current.ParsedObject);
                    t.GetNextToken();
                    cont = false;
                    break;

                case TokenType.Operator:
                {
                    // An operator here is considered a unary operator.
                    switch (t.Current.Text)
                    {
                    case "-": applyNegative = true; break;

                    case "!": applyNot = true; break;

                    default: throw new Exception("Unexpected operator: " + t.Current.Text);
                    }
                    t.GetNextToken();
                    continue;
                }

                case TokenType.Identifier:
                    left = ReadIdentifier(t);
                    cont = false;
                    break;

                case TokenType.OpenParens:
                    t.GetNextToken();
                    left = ReadExpression(t, TokenPriority.None);
                    t.GetNextToken();
                    if (left is CodeTypeReferenceExpression)
                    {
                        left = new CodeCastExpression((left as CodeTypeReferenceExpression).Type, ReadExpression(t, TokenPriority.None));
                    }
                    cont = false;
                    break;
                }
                if (t.IsInvalid)
                {
                    cont = false;
                }
            }
            if (left == null)
            {
                throw new Exception("No expression found.");
            }
            if (applyNot)
            {
                left = new CodeBinaryOperatorExpression(left, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(false));
            }
            else if (applyNegative)
            {
                left = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(0), CodeBinaryOperatorType.Subtract, left);
            }
            if (t.IsInvalid || t.Current.Type == TokenType.CloseParens || t.Current.Type == TokenType.Comma ||
                t.Current.Type == TokenType.CloseBracket)
            {
                return(left);
            }
            cont = true;
            while (cont && !t.IsInvalid)
            {
                Token token = t.Current;
                switch (token.Type)
                {
                case TokenType.Operator:
                {
                    if (t.Current.Priority < priority)
                    {
                        cont = false;
                    }
                    else
                    {
                        // In the case we have an operator, we'll assume it's a binary operator.
                        CodeBinaryOperatorType binOp;
                        bool notEquals = false;
                        switch (token.Text)
                        {
                        case ">":       binOp = CodeBinaryOperatorType.GreaterThan; break;

                        case ">=":      binOp = CodeBinaryOperatorType.GreaterThanOrEqual; break;

                        case "<":       binOp = CodeBinaryOperatorType.LessThan; break;

                        case "<=":      binOp = CodeBinaryOperatorType.LessThanOrEqual; break;

                        case "=":
                        case "==":      binOp = CodeBinaryOperatorType.ValueEquality; break;

                        case "!=":      binOp = CodeBinaryOperatorType.ValueEquality; notEquals = true; break;

                        case "|":       binOp = CodeBinaryOperatorType.BitwiseOr; break;

                        case "||":      binOp = CodeBinaryOperatorType.BooleanOr; break;

                        case "&":       binOp = CodeBinaryOperatorType.BitwiseAnd; break;

                        case "&&":      binOp = CodeBinaryOperatorType.BooleanAnd; break;

                        case "-":       binOp = CodeBinaryOperatorType.Subtract; break;

                        case "+":       binOp = CodeBinaryOperatorType.Add; break;

                        case "/":       binOp = CodeBinaryOperatorType.Divide; break;

                        case "%":       binOp = CodeBinaryOperatorType.Modulus; break;

                        case "*":       binOp = CodeBinaryOperatorType.Multiply; break;

                        default:        throw new Exception("Unrecognized operator: " + t.Current.Text);
                        }
                        if (t.IsInvalid)
                        {
                            throw new Exception("Expected token for right side of binary expression.");
                        }
                        t.GetNextToken();
                        right = ReadExpression(t, token.Priority);
                        left  = new CodeBinaryOperatorExpression(left, binOp, right);

                        // If the operator was the not equals operator, we just negate the previous binary expression.
                        if (notEquals)
                        {
                            left = new CodeBinaryOperatorExpression(left, binOp, new CodePrimitiveExpression(false));
                        }
                    }
                    break;
                }

                case TokenType.CloseParens:
                    //t.GetNextToken();
                    cont = false;
                    break;

                case TokenType.Dot:
                    // A dot could appear after some parentheses.  In this case we need to parse
                    // what's after the dot as an identifier.
                    t.GetNextToken();
                    right = ReadIdentifier(t);
                    CodeExpression ceTemp = right;
                    while (true)
                    {
                        if (ceTemp is CodeVariableReferenceExpression)
                        {
                            left = new CodePropertyReferenceExpression(left, (ceTemp as CodeVariableReferenceExpression).VariableName);
                            break;
                        }
                        else if (ceTemp is CodePropertyReferenceExpression)
                        {
                            CodePropertyReferenceExpression cpre = ceTemp as CodePropertyReferenceExpression;
                            if (cpre.TargetObject is CodeThisReferenceExpression)
                            {
                                cpre.TargetObject = left;
                                left = cpre;
                                break;
                            }
                            else
                            {
                                ceTemp = cpre.TargetObject;
                            }
                        }
                        else if (ceTemp is CodeFieldReferenceExpression)
                        {
                            CodeFieldReferenceExpression cfre = ceTemp as CodeFieldReferenceExpression;
                            if (cfre.TargetObject is CodeThisReferenceExpression)
                            {
                                cfre.TargetObject = left;
                                left = cfre;
                                break;
                            }
                        }
                        else if (ceTemp is CodeMethodInvokeExpression)
                        {
                            CodeMethodInvokeExpression cmie = ceTemp as CodeMethodInvokeExpression;
                            if (cmie.Method.TargetObject is CodeThisReferenceExpression)
                            {
                                cmie.Method.TargetObject = left;
                                left = cmie;
                                break;
                            }
                            else
                            {
                                ceTemp = cmie.Method.TargetObject;
                            }
                        }
                        else
                        {
                            throw new Exception("Unexpected identifier found after .");
                        }
                    }
                    cont = false;
                    break;

                default:
                    throw new Exception("Token not expected: " + token.Text);
                }
            }
            return(left);
        }
コード例 #4
0
ファイル: ExpressionParser.cs プロジェクト: vershart/wd
        private ExpressionToken ParseExpression(ExpressionToken lhs, TokenPriority priority)
        {
            while (true)
            {
                if (lhs.Type == TokenType.MinusOperator)
                {
                    lhs = ParseExpression(UpcomingToken, TokenPriority.UnaryMinus);
                    if (lhs is ValueToken)
                    {
                        lhs = -lhs;
                    }
                    else
                    {
                        throw new ArgumentException($"Unary minus is valid only for ValueToken!{lhs} is not a ValueToken");
                    }
                    NextToken();
                    break;
                }
                else if (lhs.Type == TokenType.NotOperator)
                {
                    lhs = ParseExpression(UpcomingToken, TokenPriority.Not);
                    if (lhs is ValueToken)
                    {
                        lhs = !lhs;
                    }
                    else
                    {
                        throw new ArgumentException($"Unary minus is valid only for ValueToken!{lhs} is not a ValueToken");
                    }
                    NextToken();
                    break;
                }
                break;
            }

            while (UpcomingToken is OperatorToken && (UpcomingToken as OperatorToken).Priority >= priority)
            {
                OperatorToken op = UpcomingToken as OperatorToken;
                NextToken();
                ExpressionToken rhs = UpcomingToken;
                NextToken();
                while (UpcomingToken is OperatorToken && (UpcomingToken as OperatorToken).Priority > op.Priority)
                {
                    rhs = ParseExpression(rhs, (UpcomingToken as OperatorToken).Priority);
                    NextToken();
                }
                switch (op.Type)
                {
                case TokenType.PlusOperator:
                    lhs = lhs + rhs;
                    break;

                case TokenType.MinusOperator:
                    lhs = lhs - rhs;
                    break;

                case TokenType.DivideOperator:
                    lhs = lhs / rhs;
                    break;

                case TokenType.MultiplyOperator:
                    lhs = lhs * rhs;
                    break;

                case TokenType.EqualOperator:
                    lhs = ExpressionToken.AreTokensEqual(lhs, rhs);
                    break;

                case TokenType.LessOperator:
                    lhs = lhs < rhs;
                    break;

                case TokenType.GreaterOperator:
                    lhs = lhs > rhs;
                    break;

                case TokenType.LessOrEqualOperator:
                    lhs = lhs <= rhs;
                    break;

                case TokenType.GreaterOrEqualOperator:
                    lhs = lhs >= rhs;
                    break;

                case TokenType.AndOperator:
                    lhs = lhs & rhs;
                    break;

                case TokenType.OrOperator:
                    lhs = lhs | rhs;
                    break;
                }
            }
            return(lhs);
        }