예제 #1
0
        public int Parse(List <Token> tokens)
        {
            bool            hasLHV    = false;
            BinaryOperation operation = new BinaryOperation();

            for (var i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];

                switch (token.MyType)
                {
                case Token.Type.Plus:
                    operation.Operation = BinaryOperation.OperationType.Addition;
                    break;

                case Token.Type.Minus:
                    operation.Operation = BinaryOperation.OperationType.Subtraction;
                    break;

                case Token.Type.Integer:
                    if (tokens.Count == 1)
                    {
                        return(Int32.Parse(token.Text));
                    }

                    var val = new Integer(Int32.Parse(token.Text));
                    if (!hasLHV)
                    {
                        operation.LeftVal = val;
                        hasLHV            = true;
                    }
                    else
                    {
                        operation.RightVal = val;
                        var newToken     = new Token(Token.Type.Integer, operation.Value.ToString());
                        var newTokenList = new List <Token> {
                            newToken
                        };
                        newTokenList.AddRange(tokens.Skip(i + 1));
                        return(Parse(newTokenList));
                    }
                    break;

                case Token.Type.String:
                    if (token.Text.Length > 1 || !Variables.ContainsKey(token.Text[0]))
                    {
                        return(0);
                    }
                    var charVal = new Integer(Variables[token.Text[0]]);
                    if (!hasLHV)
                    {
                        operation.LeftVal = charVal;
                        hasLHV            = true;
                    }
                    else
                    {
                        operation.RightVal = charVal;
                        var newToken     = new Token(Token.Type.Integer, operation.Value.ToString());
                        var newTokenList = new List <Token> {
                            newToken
                        };
                        newTokenList.AddRange(tokens.Skip(i + 1));
                        return(Parse(newTokenList));
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(0);
        }
예제 #2
0
        private IElement Parse(IReadOnlyList <Token> tokens)
        {
            var result    = new BinaryOperation();
            var opDefined = false;

            bool IsFinalOperand(int index, Token token, IElement element)
            {
                if (result.Left == null && !opDefined)
                {
                    result.Left = element;
                }
                else if (!opDefined)
                {
                    throw new ExceptionParseError($"Incorrect token: {token}");
                }
                else
                {
                    result.Right = element;
                }

                return(index == tokens.Count - 1);
            }

            void ResetResult()
            {
                var r0 = new BinaryOperation()
                {
                    Left = result, Right = null
                };

                result    = r0;
                opDefined = false;
            }

            for (int i = 0; i < tokens.Count; i++)
            {
                var token = tokens[i];
                switch (token.TokenType)
                {
                case Token.Type.IntConst:
                    var c = new Integer(int.Parse(token.Text));
                    if (!IsFinalOperand(i, token, c) && opDefined)
                    {
                        ResetResult();
                    }
                    break;

                case Token.Type.IntVar:
                    var v = new IntVar(token.Text[0], this);
                    if (!IsFinalOperand(i, token, v) && opDefined)
                    {
                        ResetResult();
                    }
                    break;

                case Token.Type.Plus:
                    opDefined            = true;
                    result.OperationType = BinaryOperation.Type.Addition;
                    break;

                case Token.Type.Minus:
                    opDefined            = true;
                    result.OperationType = BinaryOperation.Type.Subtraction;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(opDefined ? result : result.Left);
        }