示例#1
0
        /**
         * Symbol parser generates token of type TokenType.Symbol.
         * If successful, 'true' is returned, 'result' contains token, 'next' contains further index information.
         * If not successful, 'false' is returned, other values can be arbitrary.
         */
        public static bool ParseSymbol(string source, int index, out SymbolToken result, out int next)
        {
            result = null;
            next = -1;


            var specialDouble = new[]
                {">>", "<<", "**", "<>", "><", "<=", ">=", ":=", "+=", "-=", "*=", "/=", "(*", "*)", "(.", ".)", "//"};
            if (specialDouble.Any(s => TokenParseUtility.HasPrefix(source, index, s)))
            {
                result = new SymbolToken();
                result._from = index;
                result._to = index + 2;
                next = index + 2;
                return true;
            }
            
            if (index < source.Length)
            {
                return false;
            }

            var ch = source[index];
            if ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789’+-*/=<>[].,():^@{}$#&%".Contains(ch))
            {
                result = new SymbolToken();
                result._from = index;
                result._to = index + 1;
                next = index + 1;
                return true;
            }

            return false;
        }
示例#2
0
        /**
         * Comment parser generates token of type TokenType.Comment.
         * If successful, 'true' is returned, 'result' contains token, 'next' contains further index information.
         * If not successful, 'false' is returned, other values can be arbitrary.
         *
         * Note, that list of comment tokens are returned!
         */
        public static bool ParseComment(string source, int index, out List <CommentToken> result, out int next)
        {
            LinkedList <(int, string)> closeStack = new LinkedList <(int, string)>();
            bool singleLine = false;
            var  startIndex = index;

            if (TokenParseUtility.HasPrefix(source, index, "(*"))
            {
                closeStack.AddFirst((index, "*)"));
                index += 2;
            }
            else if (TokenParseUtility.HasPrefix(source, index, "{"))
            {
                closeStack.AddFirst((index, "}"));
                index += 1;
            }
            else if (TokenParseUtility.HasPrefix(source, index, "//"))
            {
                index     += 2;
                singleLine = true;
            }
            else
            {
                result = null;
                next   = -1;
                return(false);
            }

            result = new List <CommentToken>();

            while (index <= source.Length)
            {
                if (singleLine && (index == source.Length || source[index] == '\n'))
                {
                    // single line comment ended
                    var singleCommentToken = new CommentToken();
                    singleCommentToken._from = startIndex;
                    singleCommentToken._to   = index;
                    result.Add(singleCommentToken);
                    next = index;
                    return(true);
                }
                // for other cases, break the loop
                if (index == source.Length)
                {
                    break;
                }


                if (closeStack.Count > 0)
                {
                    var i            = 0;
                    var prevCommType = "\n";
                    foreach (var pair in closeStack)
                    {
                        if (pair.Item2 == "\n")
                        {
                            i++;
                            continue;
                        }
                        prevCommType = pair.Item2;
                        break;
                    }

                    if (TokenParseUtility.HasPrefix(source, index, prevCommType))
                    {
                        // prefix elimination
                        for (var k = 0; k <= i; k++)
                        {
                            // put all disposed inner comments (newlined mostly)
                            var pref = closeStack.First();
                            closeStack.RemoveFirst();
                            CommentToken ct = new CommentToken();
                            ct._from = pref.Item1;
                            ct._to   = index;
                            if (k == i)
                            {
                                ct._to += pref.Item2.Length;
                            }
                            result.Add(ct);
                        }
                        index += prevCommType.Length;
                        // put intermediate comment
                        if (closeStack.Count == 0 && !singleLine)
                        {
                            // that's all ended
                            next = index;
                            return(true);
                        }
                        continue; // don't forget to continue main loop with new index
                    }
                }

                if (TokenParseUtility.HasPrefix(source, index, "(*"))
                {
                    closeStack.AddFirst((index, "*)"));
                    index += 2;
                    continue;
                }
                else if (TokenParseUtility.HasPrefix(source, index, "{"))
                {
                    closeStack.AddFirst((index, "}"));
                    index += 1;
                    continue;
                }
                else if (TokenParseUtility.HasPrefix(source, index, "//"))
                {
                    closeStack.AddFirst((index, "\n"));
                    index += 1;
                    continue;
                }

                // else this is just the char, skip...
                index++;
            }

            next = index;
            return(closeStack.Count == 0);
        }