コード例 #1
0
ファイル: TokenReader.cs プロジェクト: nullai/LeeLang
        public TokenValue LoadToken()
        {
            TokenValue r;
            string     val;

_start:
            int x = row;
            int y = column;

            switch (peek_char(0))
            {
            case '\0':
                return(null);

            case ' ':
            case '\r':
            case '\n':
            case '\t':
                get_char();
                goto _start;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                val = LoadNumber();
                r   = new TokenValue(Token.NUMBER_LITERAL, val, new Location(file, x, y));
                return(r);

            case 'a':
            case 'b':
            case 'c':
            case 'd':
            case 'e':
            case 'f':
            case 'g':
            case 'h':
            case 'i':
            case 'j':
            case 'k':
            case 'l':
            case 'm':
            case 'n':
            case 'o':
            case 'p':
            case 'q':
            case 'r':
            case 's':
            case 't':
            case 'u':
            case 'v':
            case 'w':
            case 'x':
            case 'y':
            case 'z':
            case 'A':
            case 'B':
            case 'C':
            case 'D':
            case 'E':
            case 'F':
            case 'G':
            case 'H':
            case 'I':
            case 'J':
            case 'K':
            case 'L':
            case 'M':
            case 'N':
            case 'O':
            case 'P':
            case 'Q':
            case 'R':
            case 'S':
            case 'T':
            case 'U':
            case 'V':
            case 'W':
            case 'X':
            case 'Y':
            case 'Z':
            case '_':
                val = LoadIdentifier();
                r   = new TokenValue(val, new Location(file, x, y));
                return(r);

            case '{':
                get_char();
                r = new TokenValue(Token.OPEN_BRACE, "{", new Location(file, x, y));
                close_token.Push(r);
                return(r);

            case '}':
                get_char();
                r = new TokenValue(Token.CLOSE_BRACE, "}", new Location(file, x, y));
                PopCloseToen(Token.OPEN_BRACE);
                return(r);

            case '(':
                get_char();
                r = new TokenValue(Token.OPEN_PARENS, "(", new Location(file, x, y));
                close_token.Push(r);
                return(r);

            case ')':
                get_char();
                r = new TokenValue(Token.CLOSE_PARENS, ")", new Location(file, x, y));
                PopCloseToen(Token.OPEN_PARENS);
                return(r);

            case '[':
                get_char();
                r = new TokenValue(Token.OPEN_BRACKET, "[", new Location(file, x, y));
                close_token.Push(r);
                return(r);

            case ']':
                get_char();
                r = new TokenValue(Token.CLOSE_BRACKET, "]", new Location(file, x, y));
                PopCloseToen(Token.OPEN_BRACKET);
                return(r);

            case '.':
                get_char();
                r = new TokenValue(Token.DOT, ".", new Location(file, x, y));
                return(r);

            case ',':
                get_char();
                r = new TokenValue(Token.COMMA, ",", new Location(file, x, y));
                return(r);

            case ':':
                get_char();
                r = new TokenValue(Token.COLON, ":", new Location(file, x, y));
                return(r);

            case ';':
                get_char();
                r = new TokenValue(Token.SEMICOLON, ";", new Location(file, x, y));
                PopCloseToen(Token.SEMICOLON);
                return(r);

            case '~':
                r = new TokenValue(Token.TILDE, "~", new Location(file, x, y));
                get_char();
                return(r);

            case '+':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_ADD_ASSIGN, "+=", new Location(file, x, y));
                }
                else if (peek_char(0) == '+')
                {
                    get_char();
                    r = new TokenValue(Token.OP_INC, "++", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.PLUS, "+", new Location(file, x, y));
                }
                return(r);

            case '-':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_SUB_ASSIGN, "-=", new Location(file, x, y));
                }
                else if (peek_char(0) == '-')
                {
                    get_char();
                    r = new TokenValue(Token.OP_DEC, "--", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.MINUS, "-", new Location(file, x, y));
                }
                return(r);

            case '*':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_MULT_ASSIGN, "*=", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.STAR, "*", new Location(file, x, y));
                }
                return(r);

            case '%':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_MOD_ASSIGN, "%=", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.PERCENT, "%", new Location(file, x, y));
                }
                return(r);

            case '/':
                get_char();
                if (peek_char(0) == '/')
                {
                    while (true)
                    {
                        char ch = get_char();
                        if (ch == '\n')
                        {
                            goto _start;
                        }
                        if (ch == '\0')
                        {
                            return(null);
                        }
                    }
                }
                if (peek_char(0) == '*')
                {
                    get_char();
                    while (true)
                    {
                        char ch = get_char();
                        if (ch == '*' && peek_char(0) == '/')
                        {
                            get_char();
                            goto _start;
                        }
                        if (ch == '\0')
                        {
                            throw new Exception("不期望的文件结尾");
                        }
                    }
                }
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_DIV_ASSIGN, "/=", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.DIV, "/", new Location(file, x, y));
                }
                return(r);

            case '!':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_NE, "!=", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.BANG, "!", new Location(file, x, y));
                }
                return(r);

            case '=':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_EQ, "==", new Location(file, x, y));
                }
                else if (peek_char(0) == '>')
                {
                    get_char();
                    r = new TokenValue(Token.ARROW, "=>", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.ASSIGN, "!", new Location(file, x, y));
                }
                return(r);

            case '<':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_LE, "<=", new Location(file, x, y));
                }
                else if (peek_char(0) == '<')
                {
                    get_char();
                    if (peek_char(0) == '=')
                    {
                        get_char();
                        r = new TokenValue(Token.OP_SHIFT_LEFT_ASSIGN, "<<=", new Location(file, x, y));
                    }
                    else
                    {
                        r = new TokenValue(Token.OP_SHIFT_LEFT, "<<", new Location(file, x, y));
                    }
                }
                else
                {
                    r = new TokenValue(Token.OP_LT, "<", new Location(file, x, y));
                    close_token.Push(r);
                }
                return(r);

            case '>':
                get_char();
                if (close_token.Count > 0)
                {
                    var p = close_token.Peek();
                    if (p.token == Token.OP_LT)
                    {
                        close_token.Pop();
                        p.token = Token.GENERIC_LT;
                        r       = new TokenValue(Token.GENERIC_GT, ">", new Location(file, x, y));
                        return(r);
                    }
                }
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_GE, ">=", new Location(file, x, y));
                }
                else if (peek_char(0) == '>')
                {
                    get_char();
                    if (peek_char(0) == '=')
                    {
                        get_char();
                        r = new TokenValue(Token.OP_SHIFT_RIGHT_ASSIGN, ">>=", new Location(file, x, y));
                    }
                    else
                    {
                        r = new TokenValue(Token.OP_SHIFT_RIGHT, ">>", new Location(file, x, y));
                    }
                }
                else
                {
                    r = new TokenValue(Token.OP_GT, ">", new Location(file, x, y));
                }
                return(r);

            case '&':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_AND_ASSIGN, "&=", new Location(file, x, y));
                }
                else if (peek_char(0) == '&')
                {
                    get_char();
                    r = new TokenValue(Token.OP_AND, "&&", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.BITWISE_AND, "&", new Location(file, x, y));
                }
                return(r);

            case '|':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_OR_ASSIGN, "|=", new Location(file, x, y));
                }
                else if (peek_char(0) == '|')
                {
                    get_char();
                    r = new TokenValue(Token.OP_OR, "||", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.BITWISE_OR, "|", new Location(file, x, y));
                }
                return(r);

            case '^':
                get_char();
                if (peek_char(0) == '=')
                {
                    get_char();
                    r = new TokenValue(Token.OP_XOR_ASSIGN, "^=", new Location(file, x, y));
                }
                else
                {
                    r = new TokenValue(Token.XOR, "^", new Location(file, x, y));
                }
                return(r);

            case '?':
                get_char();
                r = new TokenValue(Token.INTERR, "?", new Location(file, x, y));
                return(r);

            case '\'':
            case '\"':
                val = LoadString(false);
                r   = new TokenValue(Token.STRING_LITERAL, val, new Location(file, x, y));
                return(r);

            case '@':
                if (peek_char(0) == '\'' || peek_char(0) == '\"')
                {
                    get_char();
                    val = LoadString(true);
                    r   = new TokenValue(Token.STRING_LITERAL, val, new Location(file, x, y));
                    return(r);
                }
                goto default;

            default:
                throw new Exception("无效字符:" + peek_char(0));
            }
        }
コード例 #2
0
        static void PrintValue(string name, object v, int tab)
        {
            if (v == null)
            {
                PrintLine(name + " : null", tab);
                return;
            }
            var t = v.GetType();

            if (v is string || v is int || t.IsEnum || v is bool)
            {
                PrintLine(name + " : " + v, tab);
                return;
            }
            if (v is Location)
            {
                return;
            }
            if (v is TokenValue)
            {
                TokenValue k = v as TokenValue;
                PrintLine(name + " : " + k.value, tab);
                return;
            }
            if (t.Name == "List`1")
            {
                System.Collections.IList dict = v as System.Collections.IList;
                var count = dict.Count;
                PrintLine(name + " : List[" + count + "]", tab);

                int i = 0;
                foreach (object p in dict)
                {
                    PrintValue("[" + i + "]", p, tab + 1);
                    ++i;
                }

                return;
            }
            if (t.IsArray)
            {
                Array a     = v as Array;
                var   count = a.Length;
                PrintLine(name + " : Array[" + count + "]", tab);
                for (int i = 0; i < count; i++)
                {
                    PrintValue("[" + i + "]", a.GetValue(i), tab + 1);
                }
                return;
            }
            if (t.Name == "Dictionary`2")
            {
                System.Collections.IDictionary dict = v as System.Collections.IDictionary;
                var count = dict.Count;
                PrintLine(name + " : Dictionary[" + count + "]", tab);
                foreach (System.Collections.DictionaryEntry p in dict)
                {
                    PrintValue("[" + p.Key + "]", p.Value, tab + 1);
                }
                return;
            }
            PrintLine(name + " : " + t.Name, tab);
            PrintAst(v, tab + 1);
        }