The parse engine of YAMP. This engine has been introduced with YAMP v1.2 and is called YAMP-PE, which stands for YAMP-ParseEngine.
예제 #1
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw = new IfKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
                return kw;
            }

            if (chars[index] == '(')
            {
                var ln = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Condition = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));

                if (kw.Condition.Container == null || !kw.Condition.Container.HasContent)
                {
                    engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
                }

                kw.Body = engine.ParseStatement();
            }
            else
            {
                engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
            }

            kw.Length = engine.Pointer - start;
            return kw;
        }
예제 #2
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var chars = engine.Characters;

            if (chars[start] == '{')
            {
                var index = start;
                var line = engine.CurrentLine;
                var column = engine.CurrentColumn;
                engine.Advance();
                index++;
                var query = engine.Query;
                var scope = new QueryContext(query, query.Input.Substring(index));
                var eng = scope.Parser.SetOffset(line, column + 1).Parse();

                if (!eng.IsTerminated)
                {
                    engine.AddError(new YAMPScopeNotClosedError(line, column));
                }

                foreach (var error in eng.Errors)
                {
                    engine.AddError(error);
                }

                engine.Advance(eng.Pointer);
                return new GroupExpression(line, column, engine.Pointer - start, scope);
            }

            return null;
        }
예제 #3
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw    = new IfKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
                return(kw);
            }

            if (chars[index] == '(')
            {
                var ln  = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Condition = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));

                if (kw.Condition.Container == null || !kw.Condition.Container.HasContent)
                {
                    engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
                }

                kw.Body = engine.ParseStatement();
            }
            else
            {
                engine.AddError(new YAMPIfArgumentsMissing(engine), kw);
            }

            kw.Length = engine.Pointer - start;
            return(kw);
        }
예제 #4
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw = new ElseKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            kw.Body = engine.Advance(Token.Length).ParseStatement();

            if (engine.LastStatement == null)
            {
                engine.AddError(new YAMPIfRequiredError(engine), kw);
            }
            else if (engine.LastStatement.IsKeyword<IfKeyword>())
            {
                engine.LastStatement.GetKeyword<IfKeyword>().Else = kw;
            }
            else if (engine.LastStatement.IsKeyword<ElseKeyword>())
            {
                var otherwise = engine.LastStatement.GetKeyword<ElseKeyword>();

                if (otherwise.IsElseIf)
                {
                    otherwise.ElseIf.Else = kw;
                }
                else
                {
                    engine.AddError(new YAMPSingleElseError(engine), kw);
                }
            }
            else
            {
                engine.AddError(new YAMPIfRequiredError(engine), kw);
            }

            kw.Length = engine.Pointer - start;
            return kw;
        }
예제 #5
0
 /// <summary>
 /// Creates a new query context.
 /// </summary>
 /// <param name="context">The context to reference.</param>
 /// <param name="input">The input to parse</param>
 public QueryContext(ParseContext context, String input)
     : this(context)
 {
     _input = input;
     _parser = new ParseEngine(this, context);
     _functionBuffer = new Dictionary<String, IFunction>();
 }
예제 #6
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var chars = engine.Characters;

            if (chars[start] == '(')
            {
                var index = start;
                var line = engine.CurrentLine;
                var col = engine.CurrentColumn;
                var container = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(line, col), (ch, statement) =>
                {
                    if (ch == ',')
                    {
                        var op = new CommaOperator(engine);
                        engine.Advance();
                        statement.Push(engine, op);
                        return true;
                    }

                    return false;
                }).Container;

                var exp = new BracketExpression(line, col, engine.Pointer - start, engine.Query, container ?? new ContainerExpression());

                if (container == null)
                {
                    engine.AddError(new YAMPBracketEmptyError(line, col), exp);
                }

                return exp;
            }

            return null;
        }
예제 #7
0
        protected void SetMarker(ParseEngine engine)
        {
            hasMarker = engine.HasMarker(Marker.Breakable);

            if (!hasMarker)
                engine.InsertMarker(Marker.Breakable);
        }
예제 #8
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var chars = engine.Characters;

            if (chars[start] == '(')
            {
                var index     = start;
                var line      = engine.CurrentLine;
                var col       = engine.CurrentColumn;
                var container = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(line, col), (ch, statement) =>
                {
                    if (ch == ',')
                    {
                        var op = new CommaOperator(engine);
                        engine.Advance();
                        statement.Push(engine, op);
                        return(true);
                    }

                    return(false);
                }).Container;

                var exp = new BracketExpression(line, col, engine.Pointer - start, engine.Query, container ?? new ContainerExpression());

                if (container == null)
                {
                    engine.AddError(new YAMPBracketEmptyError(line, col), exp);
                }

                return(exp);
            }

            return(null);
        }
예제 #9
0
        String FindArbitraryOperator(IEnumerable <String> operators, ParseEngine engine)
        {
            var maxop    = String.Empty;
            var notfound = true;
            var chars    = engine.Characters;
            var ptr      = engine.Pointer;
            var rest     = chars.Length - ptr;

            foreach (var op in operators)
            {
                if (op.Length <= rest && op.Length > maxop.Length)
                {
                    notfound = false;

                    for (var i = 0; !notfound && i < op.Length; i++)
                    {
                        notfound = (chars[ptr + i] != op[i]);
                    }

                    if (!notfound)
                    {
                        maxop = op;
                    }
                }
            }

            return(maxop);
        }
예제 #10
0
        public override Expression Scan(ParseEngine engine)
        {
            var index = engine.Pointer;
            var chars = engine.Characters;

            if (ParseEngine.IsIdentifierStart(chars[index]))
            {
                index++;

                while (index < chars.Length && ParseEngine.IsIdentifierPart(chars[index]))
                {
                    index++;
                }

                var name = new String(chars, engine.Pointer, index - engine.Pointer);

                if (engine.UseKeywords)
                {
                    var keyword = engine.Elements.FindKeywordExpression(name, engine);

                    if (keyword != null)
                    {
                        return(keyword);
                    }
                }

                var exp = new SymbolExpression(engine, name);
                engine.SetPointer(index);
                return(exp);
            }

            return(null);
        }
예제 #11
0
        public ScalarValue Function(StringValue octstr)
        {
            var sum    = 0;
            var hex    = new Stack <Int32>();
            var weight = 1;

            for (var i = 1; i <= octstr.Length; i++)
            {
                var chr = octstr[i];

                if (!ParseEngine.IsWhiteSpace(chr) && !ParseEngine.IsNewLine(chr))
                {
                    if (chr >= '0' && chr <= '7')
                    {
                        hex.Push((Int32)(chr - '0'));
                    }
                    else
                    {
                        throw new YAMPRuntimeException("oct2dec can only interpret octal strings.");
                    }
                }
            }

            while (hex.Count != 0)
            {
                var el = hex.Pop();
                sum    += weight * el;
                weight *= 8;
            }

            return(new ScalarValue(sum));
        }
예제 #12
0
        public override Expression Scan(ParseEngine engine)
        {
            var kw    = new ForKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var start = engine.Pointer;
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPForArgumentsMissing(engine));
                return(kw);
            }

            if (chars[index] == '(')
            {
                var ln  = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Initialization    = engine.Advance().ParseStatement();
                kw.Condition         = engine.ParseStatement();
                kw.Condition.IsMuted = false;
                kw.End = engine.ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));
                SetMarker(engine);
                kw.Body = engine.ParseStatement();
                UnsetMarker(engine);
            }
            else
            {
                engine.AddError(new YAMPForArgumentsMissing(engine));
            }

            kw.Length = engine.Pointer - start;
            return(kw);
        }
예제 #13
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var chars = engine.Characters;

            if (chars[start] == '{')
            {
                var index  = start;
                var line   = engine.CurrentLine;
                var column = engine.CurrentColumn;
                engine.Advance();
                index++;
                var query = engine.Query;
                var scope = new QueryContext(query, query.Input.Substring(index));
                var eng   = scope.Parser.SetOffset(line, column + 1).Parse();

                if (!eng.IsTerminated)
                {
                    engine.AddError(new YAMPScopeNotClosedError(line, column));
                }

                foreach (var error in eng.Errors)
                {
                    engine.AddError(error);
                }

                engine.Advance(eng.Pointer);
                return(new GroupExpression(line, column, engine.Pointer - start, scope));
            }

            return(null);
        }
예제 #14
0
 protected void UnsetMarker(ParseEngine engine)
 {
     if (!hasMarker)
     {
         engine.RemoveMarker(Marker.Breakable);
     }
 }
 /// <summary>
 /// Creates a new query context.
 /// </summary>
 /// <param name="context">The context to reference.</param>
 /// <param name="input">The input to parse</param>
 public QueryContext(ParseContext context, String input)
     : this(context)
 {
     _input          = input;
     _parser         = new ParseEngine(this, context);
     _functionBuffer = new Dictionary <String, IFunction>();
 }
예제 #16
0
 public override Expression Scan(ParseEngine engine)
 {
     var start = engine.Pointer;
     var kw = new DoKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
     var index = engine.Advance(Token.Length).Pointer;
     kw.Body = engine.ParseStatement();
     kw.Length = engine.Pointer - start;
     return kw;
 }
예제 #17
0
        /// <summary>
        /// Searches for the given keyword in the list of available keywords. Creates a class if the keyword is found.
        /// </summary>
        /// <param name="keyword">The keyword to look for.</param>
        /// <param name="engine">The engine to use.</param>
        /// <returns>Keyword that matches the given keyword.</returns>
        public Expression FindKeywordExpression(string keyword, ParseEngine engine)
        {
            if (keywords.ContainsKey(keyword))
            {
                return(keywords[keyword].Scan(engine));
            }

            return(null);
        }
예제 #18
0
        protected void SetMarker(ParseEngine engine)
        {
            hasMarker = engine.HasMarker(Marker.Breakable);

            if (!hasMarker)
            {
                engine.InsertMarker(Marker.Breakable);
            }
        }
예제 #19
0
        /// <summary>
        /// Finalizes the statement by analyzing the contained objects and creating
        /// the container.
        /// </summary>
        /// <param name="engine">The current parse engine.</param>
        /// <returns>The current (finalized) instance.</returns>
        internal Statement Finalize(ParseEngine engine)
        {
            if (finalized)
            {
                return(this);
            }

            if (errors.Count != 0)
            {
                foreach (var error in errors)
                {
                    engine.AddError(error);
                }

                return(this);
            }

            if (_expressions.Count == 0 && _operators.Count > 0)
            {
                engine.AddError(new YAMPExpressionMissingError(engine));
                return(this);
            }

            while (_operators.Count > 0)
            {
                var op  = _operators.Pop();
                var exp = new Expression[op.Expressions];

                if (_expressions.Count < op.Expressions)
                {
                    engine.AddError(new YAMPExpressionMissingError(engine, op, _expressions.Count));
                    return(this);
                }

                for (var i = op.Expressions - 1; i >= 0; i--)
                {
                    exp[i] = _expressions.Pop();
                }

                var container = new ContainerExpression(exp, op);
                _expressions.Push(container);
                ReduceUnary(container);
            }

            if (_expressions.Count == 1)
            {
                _container = new ContainerExpression(_expressions.Pop());
            }
            else
            {
                _container = new ContainerExpression();
            }

            finalized = true;
            return(this);
        }
예제 #20
0
        /// <summary>
        /// Creates a new instance of the current operator.
        /// </summary>
        /// <param name="engine">The engine that is used for parsing the query.</param>
        /// <returns>The new instance.</returns>
        public virtual Operator Create(ParseEngine engine)
        {
            var op = Create();

            op.Query       = engine.Query;
            op.StartColumn = engine.CurrentColumn;
            op.StartLine   = engine.CurrentLine;
            engine.Advance(Op.Length);
            return(op);
        }
예제 #21
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw    = new DoKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var index = engine.Advance(Token.Length).Pointer;

            kw.Body   = engine.ParseStatement();
            kw.Length = engine.Pointer - start;
            return(kw);
        }
예제 #22
0
        /// <summary>
        /// Finds the closest matching left unary operator.
        /// </summary>
        /// <param name="engine">The engine to parse the query.</param>
        /// <returns>Operator that matches the current characters.</returns>
        public Operator FindLeftUnaryOperator(ParseEngine engine)
        {
            var maxop = FindArbitraryOperator(unaryOperators.Keys, engine);

            if (maxop.Length == 0)
            {
                return(null);
            }

            return(unaryOperators[maxop].Create(engine));
        }
예제 #23
0
        /// <summary>
        /// Pushes an expression to the stack.
        /// </summary>
        /// <param name="engine">The current parse engine.</param>
        /// <param name="_expression">The expression to add.</param>
        /// <returns>The current instance.</returns>
        internal Statement Push(ParseEngine engine, Expression _expression)
        {
            if (finalized)
                return this;

            if (_expressions.Count == 0)
                IsFinished = _expression == null ? false : _expression.IsSingleStatement;

            _expressions.Push(_expression ?? Expression.Empty);
            takeOperator = true;
            return this;
        }
예제 #24
0
        /// <summary>
        /// Pushes an operator to the stack.
        /// </summary>
        /// <param name="engine">The current parse engine.</param>
        /// <param name="_operator">The operator to add.</param>
        /// <returns>The current instance.</returns>
        internal Statement Push(ParseEngine engine, Operator _operator)
        {
            if (finalized)
                return this;

            _operator = _operator ?? Operator.Void;

            if (_operator.Expressions == 1 && _operator.IsRightToLeft)
            {
                _expressions.Push(new ContainerExpression(_expressions.Pop(), _operator));
            }
            else
            {
                if (_operator.Expressions == 2)
                {
                    if (_operator.Level >= (_operator.IsRightToLeft ? maxLevel : maxLevel + 1))
                        maxLevel = _operator.Level;
                    else
                    {
                        while (true)
                        {
                            var count = _operators.Peek().Expressions;

                            if (count > _expressions.Count)
                            {
                                errors.Add(new YAMPExpressionMissingError(_operator.StartLine, _operator.StartColumn));
                                break;
                            }

                            var exp = new Expression[count];

                            for (var i = count - 1; i >= 0; i--)
                                exp[i] = _expressions.Pop();

                            var container = new ContainerExpression(exp, _operators.Pop());
                            _expressions.Push(container);
                            ReduceUnary(container);

                            if (_operators.Count > 0 && _operators.Peek().Level > _operator.Level)
                                continue;

                            maxLevel = _operator.Level;
                            break;
                        }
                    }
                }

                _operators.Push(_operator);
                takeOperator = false;
            }

            return this;
        }
예제 #25
0
        public override Expression Scan(ParseEngine engine)
        {
            var kw = new BreakKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            engine.Advance(Token.Length);

            if (!IsBreakable(engine))
            {
                engine.AddError(new YAMPKeywordNotPossible(engine, Token), kw);
            }

            return kw;
        }
예제 #26
0
        public override Expression Scan(ParseEngine engine)
        {
            var kw = new BreakKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);

            engine.Advance(Token.Length);

            if (!IsBreakable(engine))
            {
                engine.AddError(new YAMPKeywordNotPossible(engine, Token), kw);
            }

            return(kw);
        }
예제 #27
0
        /// <summary>
        /// Finds the closest matching expression.
        /// </summary>
        /// <param name="engine">The engine to parse the query.</param>
        /// <returns>Expression that matches the current characters.</returns>
        public Expression FindExpression(ParseEngine engine)
        {
            foreach (var origin in expressions)
            {
                var exp = origin.Scan(engine);

                if (exp != null)
                {
                    return(exp);
                }
            }

            return(null);
        }
예제 #28
0
        bool IsBreakable(ParseEngine engine)
        {
            if (engine.HasMarker(Marker.Breakable))
            {
                return(true);
            }

            if (engine.Parent != null)
            {
                return(IsBreakable(engine.Parent));
            }

            return(false);
        }
예제 #29
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw    = new WhileKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
                return(kw);
            }

            if (chars[index] == '(')
            {
                var ln  = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Condition = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));

                if (kw.Condition.Container == null || !kw.Condition.Container.HasContent)
                {
                    engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
                }

                SetMarker(engine);
                kw.Body = engine.ParseStatement();
                UnsetMarker(engine);

                if (engine.LastStatement != null && engine.LastStatement.IsKeyword <DoKeyword>())
                {
                    if (kw.Body.IsEmpty)
                    {
                        IsDoWhile = true;
                        engine.LastStatement.GetKeyword <DoKeyword>().While = kw;
                    }
                    else
                    {
                        engine.AddError(new YAMPDoWhileNotEmptyError(engine), kw);
                    }
                }
            }
            else
            {
                engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
            }

            kw.Length = engine.Pointer - start;
            return(kw);
        }
예제 #30
0
        Boolean IsBreakable(ParseEngine engine)
        {
            if (!engine.HasMarker(Marker.Breakable))
            {
                if (engine.Parent != null)
                {
                    return IsBreakable(engine.Parent);
                }

                return false;
            }

            return true;
        }
예제 #31
0
        public override Expression Scan(ParseEngine engine)
        {
            foreach (var specialExpression in specialExpressions)
            {
                if (Compare(engine.Characters, engine.Pointer, specialExpression.Key))
                {
                    var exp = new SpecialExpression(engine, specialExpression.Key);
                    engine.Advance();
                    exp.specialValue = specialExpression.Value;
                    return(exp);
                }
            }

            return(null);
        }
예제 #32
0
        public override Expression Scan(ParseEngine engine)
        {
            var chars = engine.Characters;
            var start = engine.Pointer;

            if (chars[start] == '|')
            {
                var line = engine.CurrentLine;
                var col = engine.CurrentColumn;
                var container = engine.Advance().ParseStatement('|', e => new YAMPTerminatorMissingError(line, col, '|')).Container;
                return new AbsExpression(line, col, engine.Pointer - start, engine.Query, container);
            }

            return null;
        }
        public override Expression Scan(ParseEngine engine)
        {
            var chars = engine.Characters;
            var start = engine.Pointer;

            if (chars[start] == '|')
            {
                var line      = engine.CurrentLine;
                var col       = engine.CurrentColumn;
                var container = engine.Advance().ParseStatement('|', e => new YAMPTerminatorMissingError(line, col, '|')).Container;
                return(new AbsExpression(line, col, engine.Pointer - start, engine.Query, container));
            }

            return(null);
        }
예제 #34
0
        public override Expression Scan(ParseEngine engine)
        {
            foreach(var specialExpression in specialExpressions)
            {
                if (Compare(engine.Characters, engine.Pointer, specialExpression.Key))
                {
                    var exp = new SpecialExpression(engine, specialExpression.Key);
                    engine.Advance();
                    exp._specialValue = specialExpression.Value;
                    return exp;
                }
            }

            return null;
        }
예제 #35
0
        public Value Function(StringValue code)
        {
            var c = new ParseContext(Context);
            var q = new QueryContext(c, code.Value);
            var p = new ParseEngine(q, c).Parse();

            if (p.CanRun)
            {
                foreach (var statement in p.Statements)
                {
                    return statement.Interpret(new Dictionary<String, Value>());
                }
            }

            return new StringValue();
        }
예제 #36
0
        /// <summary>
        /// Pushes an expression to the stack.
        /// </summary>
        /// <param name="engine">The current parse engine.</param>
        /// <param name="_expression">The expression to add.</param>
        /// <returns>The current instance.</returns>
        internal Statement Push(ParseEngine engine, Expression _expression)
        {
            if (_finalized)
            {
                return(this);
            }

            if (_expressions.Count == 0)
            {
                IsFinished = _expression == null ? false : _expression.IsSingleStatement;
            }

            _expressions.Push(_expression ?? Expression.Empty);
            _takeOperator = true;
            return(this);
        }
예제 #37
0
        public Value Function(StringValue code)
        {
            var c = new ParseContext(Context);
            var q = new QueryContext(c, code.Value);
            var p = new ParseEngine(q, c).Parse();

            if (p.CanRun)
            {
                foreach (var statement in p.Statements)
                {
                    return(statement.Interpret(new Dictionary <String, Value>()));
                }
            }

            return(new StringValue());
        }
예제 #38
0
        public ScalarValue Function(StringValue binarystr)
        {
            var sum    = 0;
            var binary = new Stack <bool>();
            var weight = 1;

            for (var i = 1; i <= binarystr.Length; i++)
            {
                var chr = binarystr[i];

                if (ParseEngine.IsWhiteSpace(chr))
                {
                    continue;
                }
                else if (ParseEngine.IsNewLine(chr))
                {
                    continue;
                }
                else if (chr == '0')
                {
                    binary.Push(false);
                }
                else if (chr == '1')
                {
                    binary.Push(true);
                }
                else
                {
                    throw new YAMPRuntimeException("bin2dec can only interpret binary strings.");
                }
            }

            while (binary.Count != 0)
            {
                var el = binary.Pop();

                if (el)
                {
                    sum += weight;
                }

                weight *= 2;
            }

            return(new ScalarValue(sum));
        }
예제 #39
0
        public ScalarValue Function(StringValue hexstr)
        {
            var sum    = 0;
            var hex    = new Stack <int>();
            var weight = 1;

            for (var i = 1; i <= hexstr.Length; i++)
            {
                var chr = hexstr[i];

                if (ParseEngine.IsWhiteSpace(chr))
                {
                    continue;
                }
                else if (ParseEngine.IsNewLine(chr))
                {
                    continue;
                }
                else if (chr >= '0' && chr <= '9')
                {
                    hex.Push((int)(chr - '0'));
                }
                else if (chr >= 'A' && chr <= 'F')
                {
                    hex.Push((int)(chr - 'A') + 10);
                }
                else if (chr >= 'a' && chr <= 'f')
                {
                    hex.Push((int)(chr - 'a') + 10);
                }
                else
                {
                    throw new YAMPRuntimeException("hex2dec can only interpret hexadecimal strings.");
                }
            }

            while (hex.Count != 0)
            {
                var el = hex.Pop();
                sum    += weight * el;
                weight *= 16;
            }

            return(new ScalarValue(sum));
        }
예제 #40
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw = new LetKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            engine.Advance(Token.Length);
            kw.Length = engine.Pointer - start;
            engine.Skip();
            start = engine.Pointer;
            kw.name = engine.Elements.FindExpression<SymbolExpression>().Scan(engine) as SymbolExpression;

            if (kw.name == null)
            {
                engine.AddError(new YAMPVariableNameMissing(engine), kw);
                return kw;
            }

            engine.SetPointer(start);
            return kw;
        }
예제 #41
0
        public override Operator Create(ParseEngine engine)
        {
            var start = engine.Pointer;

            //Arguments need to be attached directly.
            if (start == 0 || ParseEngine.IsWhiteSpace(engine.Characters[start - 1]) || ParseEngine.IsNewLine(engine.Characters[start - 1]))
            {
                return(null);
            }

            var ao = new ArgsOperator();

            ao.Query       = engine.Query;
            ao.StartLine   = engine.CurrentLine;
            ao.StartColumn = engine.CurrentColumn;
            ao._content    = Elements.Instance.FindExpression <BracketExpression>().Scan(engine);
            ao.Length      = engine.Pointer - start;
            return(ao);
        }
예제 #42
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw    = new LetKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);

            engine.Advance(Token.Length);
            kw.Length = engine.Pointer - start;
            engine.Skip();
            start   = engine.Pointer;
            kw.name = Elements.Instance.FindExpression <SymbolExpression>().Scan(engine) as SymbolExpression;

            if (kw.name == null)
            {
                engine.AddError(new YAMPVariableNameMissing(engine), kw);
                return(kw);
            }

            engine.SetPointer(start);
            return(kw);
        }
예제 #43
0
        string FindArbitraryOperator(IEnumerable <string> operators, ParseEngine engine)
        {
            var maxop    = string.Empty;
            var notfound = true;
            var chars    = engine.Characters;
            var ptr      = engine.Pointer;
            var rest     = chars.Length - ptr;

            foreach (var op in operators)
            {
                if (op.Length > rest)
                {
                    continue;
                }

                if (op.Length <= maxop.Length)
                {
                    continue;
                }

                notfound = false;

                for (var i = 0; i < op.Length; i++)
                {
                    if (notfound = (chars[ptr + i] != op[i]))
                    {
                        break;
                    }
                }

                if (notfound == false)
                {
                    maxop = op;
                }
            }

            return(maxop);
        }
예제 #44
0
        public override Operator Create(ParseEngine engine)
        {
            var start = engine.Pointer;

            //Arguments need to be attached directly.
            if (start != 0 && !ParseEngine.IsWhiteSpace(engine.Characters[start - 1]) && !ParseEngine.IsNewLine(engine.Characters[start - 1]))
            {
                var query = engine.Query;
                var line = engine.CurrentLine;
                var column = engine.CurrentColumn;
                var content = engine.Elements.FindExpression<BracketExpression>().Scan(engine);
                var length = engine.Pointer - start;

                return new ArgsOperator(content)
                {
                    Query = query,
                    StartLine = line,
                    StartColumn = column,
                    Length = length
                };
            }

            return null;
        }
예제 #45
0
        /// <summary>
        /// Scans for a function entry.
        /// </summary>
        /// <param name="engine">The current parse engine.</param>
        /// <returns>The created expression.</returns>
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw = new FunctionKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            engine.Advance(Token.Length).Skip();

            if (engine.Pointer == engine.Characters.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPFunctionNameMissing(engine), kw);
                return kw;
            }

            kw.name = engine.Elements.FindExpression<SymbolExpression>().Scan(engine) as SymbolExpression;

            if (kw.name == null)
            {
                engine.AddError(new YAMPFunctionNameMissing(engine), kw);
                return kw;
            }

            engine.Skip();

            if (engine.Pointer == engine.Characters.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPFunctionArgumentsMissing(engine), kw);
                return kw;
            }

            kw.arguments = engine.Elements.FindExpression<BracketExpression>().Scan(engine) as BracketExpression;

            if (engine.Pointer == engine.Characters.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPFunctionBodyMissing(engine), kw.arguments);
                return kw;
            }

            kw.Body = engine.ParseStatement();
            kw.Length = engine.Pointer - start;

            if (kw.Body.Container.Expressions.Length == 1 && kw.Body.Container.Expressions[0] is GroupExpression)
            {
                var container = (GroupExpression)kw.Body.Container.Expressions[0];
                var context = new ParseContext(engine.Context.Parent);
                var input = container.Scope.Input;
                container.Scope = new QueryContext(context, input);
            }
            else
            {
                engine.AddError(new YAMPFunctionBodyMissing(engine), kw.arguments);
                return kw;
            }

            if (kw.arguments == null)
            {
                engine.AddError(new YAMPFunctionArgumentsMissing(engine), kw);
                return kw;
            }
            else if (kw.arguments.HasContent && !kw.arguments.IsSymbolList)
            {
                engine.AddError(new YAMPFunctionArgumentsSymbols(engine), kw.arguments);
                return kw;
            }

            return kw;
        }
예제 #46
0
파일: Block.cs 프로젝트: FlorianRappl/YAMP
 /// <summary>
 /// Initializes the values StartColumn, StartLine and Query.
 /// </summary>
 /// <param name="engine">The engine to use for initialization.</param>
 protected void Init(ParseEngine engine)
 {
     StartColumn = engine.CurrentColumn;
     StartLine = engine.CurrentLine;
     Query = engine.Query;
 }
예제 #47
0
 /// <summary>
 /// Scans the input of the current parse engine.
 /// </summary>
 /// <param name="engine">The engine to use.</param>
 /// <returns>Null, since container expressions cannot be scanned.</returns>
 public override Expression Scan(ParseEngine engine)
 {
     return null;
 }
예제 #48
0
 public override Expression Scan(ParseEngine engine)
 {
     return new EmptyExpression();
 }
예제 #49
0
        public override Expression Scan(ParseEngine engine)
        {
            var kw = new ForKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var start = engine.Pointer;
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPForArgumentsMissing(engine));
                return kw;
            }
            else if (chars[index] == '(')
            {
                var ln = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Initialization = engine.Advance().ParseStatement();
                kw.Condition = engine.ParseStatement();
                kw.Condition.IsMuted = false;
                kw.End = engine.ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));
                SetMarker(engine);
                kw.Body = engine.ParseStatement();
                UnsetMarker(engine);
            }
            else
            {
                engine.AddError(new YAMPForArgumentsMissing(engine));
            }

            kw.Length = engine.Pointer - start;
            return kw;
        }
예제 #50
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var kw = new WhileKeyword(engine.CurrentLine, engine.CurrentColumn, engine.Query);
            var index = engine.Advance(Token.Length).Skip().Pointer;
            var chars = engine.Characters;

            if (index == chars.Length)
            {
                kw.Length = engine.Pointer - start;
                engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
                return kw;
            }

            if (chars[index] == '(')
            {
                var ln = engine.CurrentLine;
                var col = engine.CurrentColumn;
                kw.Condition = engine.Advance().ParseStatement(')', e => new YAMPBracketNotClosedError(ln, col));

                if (kw.Condition.Container == null || !kw.Condition.Container.HasContent)
                {
                    engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
                }

                SetMarker(engine);
                kw.Body = engine.ParseStatement();
                UnsetMarker(engine);

                if (engine.LastStatement != null && engine.LastStatement.IsKeyword<DoKeyword>())
                {
                    if (kw.Body.IsEmpty)
                    {
                        IsDoWhile = true;
                        engine.LastStatement.GetKeyword<DoKeyword>().While = kw;
                    }
                    else
                    {
                        engine.AddError(new YAMPDoWhileNotEmptyError(engine), kw);
                    }
                }
            }
            else
            {
                engine.AddError(new YAMPWhileArgumentsMissing(engine), kw);
            }

            kw.Length = engine.Pointer - start;
            return kw;
        }
예제 #51
0
 public StringExpression(ParseEngine engine)
     : base(engine)
 {
 }
예제 #52
0
 public NumberExpression(ParseEngine engine)
     : base(engine)
 {
 }
예제 #53
0
 protected void UnsetMarker(ParseEngine engine)
 {
     if (!hasMarker)
         engine.RemoveMarker(Marker.Breakable);
 }
예제 #54
0
        public override Expression Scan(ParseEngine engine)
        {
            var start = engine.Pointer;
            var chars = engine.Characters;
            var ch = chars[start];
            var isreal = false;

            if (ParseEngine.IsNumber(ch) || (ch == '.' && start + 1 < chars.Length && ParseEngine.IsNumber(chars[start + 1])))
            {
                var index = start;
                var exp = new NumberExpression(engine);
                var number = 0.0;
                var pow = 0;

                if (ch != '.')
                {
                    number += ToDoubleNumber(chars[index++]);

                    while (index < chars.Length && ParseEngine.IsNumber(ch = chars[index]))
                    {
                        number *= 10.0;
                        number += ToDoubleNumber(ch);
                        index++;
                    }
                }

                if (ch == '.')
                {
                    isreal = true;
                    index++;

                    if (index < chars.Length && ParseEngine.IsNumber(chars[index]))
                    {
                        do
                        {
                            number *= 10.0;
                            number += ToDoubleNumber(chars[index++]);
                            pow++;
                        }
                        while (index < chars.Length && ParseEngine.IsNumber(ch = chars[index]));
                    }
                }

                if (ch == 'e' || ch == 'E')
                {
                    isreal = true;
                    var epow = 0;
                    var sign = 1;
                    index++;

                    if (index < chars.Length && (chars[index] == '+' || chars[index] == '-'))
                    {
                        sign = chars[index] == '-' ? -1 : +1;
                        index++;
                    }

                    while (index < chars.Length && ParseEngine.IsNumber(ch = chars[index]))
                    {
                        epow *= 10;
                        epow += ToInt32Number(ch);
                        index++;
                    }

                    pow -= epow * sign;
                }

                var value = number / Math.Pow(10.0, pow);

                if (ch == 'i')
                {
                    exp.value = new ScalarValue(0.0, value);
                    index++;
                }
                else if (isreal)
                    exp.value = new ScalarValue(value);
                else
                    exp.value = new ScalarValue((int)value);

                exp.Length = index - start;
                engine.SetPointer(index);
                return exp;
            }

            return null;
        }
예제 #55
0
        /// <summary>
        /// Scans the current parse engine for a matrix expression.
        /// </summary>
        /// <param name="engine">The parse engine to use.</param>
        /// <returns>The found expression or NULL.</returns>
        public override Expression Scan(ParseEngine engine)
        {
            var column = engine.CurrentColumn;
            var line = engine.CurrentLine;
            var chars = engine.Characters;
            var start = engine.Pointer;

            if (chars[start] == '[')
            {
                engine.Advance();
                var terminated = false;
                var statement = new Statement();
                var ws = false;
                var nl = false;

                while (engine.Pointer < chars.Length && engine.IsParsing)
                {
                    if (ParseEngine.IsWhiteSpace(chars[engine.Pointer]))
                    {
                        ws = true;
                        engine.Advance();
                    }
                    else if (ParseEngine.IsNewLine(chars[engine.Pointer]))
                    {
                        nl = true;
                        engine.Advance();
                    }
                    else if (chars[engine.Pointer] == ']')
                    {
                        terminated = true;
                        engine.Advance();
                        break;
                    }
                    else if (chars[engine.Pointer] == ',')
                    {
                        ws = false;
                        nl = false;
                        statement.Push(engine, new ColumnOperator(engine));
                        engine.Advance();
                    }
                    else if (chars[engine.Pointer] == ';')
                    {
                        ws = false;
                        nl = false;
                        statement.Push(engine, new RowOperator(engine));
                        engine.Advance();
                    }
                    else if (engine.Pointer < chars.Length - 1 && ParseEngine.IsComment(chars[engine.Pointer], chars[engine.Pointer + 1]))
                    {
                        if (ParseEngine.IsLineComment(chars[engine.Pointer], chars[engine.Pointer + 1]))
                            engine.AdvanceToNextLine();
                        else
                            engine.AdvanceTo("*/");
                    }
                    else
                    {
                        engine.ParseBlock(statement, nl ? (Operator)new RowOperator(engine) : (ws ? new ColumnOperator(engine) : null));
                        ws = false;
                        nl = false;
                    }
                }

                if (!terminated)
                {
                    var err = new YAMPMatrixNotClosedError(line, column);
                    engine.AddError(err);
                }

                var container = statement.Finalize(engine).Container;
                return new MatrixExpression(line, column, engine.Pointer - start, engine.Query, container ?? new ContainerExpression());
            }

            return null;
        }
예제 #56
0
 public SpecialExpression(ParseEngine engine, String name)
     : base(engine)
 {
     _specialName = name;
     Length = name.Length;
 }
예제 #57
0
        public override Expression Scan(ParseEngine engine)
        {
            var chars = engine.Characters;
            var start = engine.Pointer;

            if (chars[start] == '"' || (chars[start] == '@' && start + 1 < chars.Length && chars[start + 1] == '"'))
            {
                var index = start;
                var exp = new StringExpression(engine);
                var escape = false;
                var terminated = false;
                var sb = new StringBuilder();

                if (chars[index] == '@')
                {
                    index += 2;
                    exp.literal = true;
                }
                else
                {
                    index++;
                }

                while (index < chars.Length)
                {
                    if (!literal && !escape && chars[index] == '\\')
                    {
                        escape = true;
                    }
                    else if (!escape && chars[index] == '"')
                    {
                        terminated = true;
                        index++;
                        break;
                    }
                    else if (escape)
                    {
                        switch (chars[index])
                        {
                            case 't':
                                sb.Append("\t");
                                break;
                            case 'n':
                                sb.AppendLine();
                                break;
                            case '\\':
                            case '"':
                                sb.Append(chars[index]);
                                break;
                            default:
                                engine.SetPointer(index);
                                engine.AddError(new YAMPEscapeSequenceNotFoundError(engine, chars[index]), exp);
                                break;
                        }

                        escape = false;
                    }
                    else
                    {
                        sb.Append(chars[index]);
                    }

                    index++;
                }

                if (!terminated)
                {
                    engine.AddError(new YAMPStringNotTerminatedError(engine), exp);
                }

                exp.value = sb.ToString();
                exp.Length = index - start;
                engine.SetPointer(index);
                return exp;
            }

            return null;
        }
예제 #58
0
 public CommaOperator(ParseEngine engine)
     : this()
 {
     StartLine = engine.CurrentLine;
     StartColumn = engine.CurrentColumn;
 }
예제 #59
0
 /// <summary>
 /// Creates a new instance of the current operator.
 /// </summary>
 /// <param name="engine">The engine that is used for parsing the query.</param>
 /// <returns>The new instance.</returns>
 public virtual Operator Create(ParseEngine engine)
 {
     var op = Create();
     op.Query = engine.Query;
     op.StartColumn = engine.CurrentColumn;
     op.StartLine = engine.CurrentLine;
     engine.Advance(Op.Length);
     return op;
 }