コード例 #1
0
ファイル: ILTokenizer.cs プロジェクト: pmq20/mono_forked
        public ILToken GetNextToken()
        {
            if (lastToken == ILToken.EOF)
            {
                return(ILToken.EOF);
            }

            int     ch;
            int     next;
            ILToken res = ILToken.EOF.Clone() as ILToken;


            while ((ch = reader.Read()) != -1)
            {
                // Comments
                if (ch == '/')
                {
                    next = reader.Peek();
                    if (next == '/')
                    {
                        // double-slash comment, skip to the end of the line.
                        for (reader.Read();
                             next != -1 && next != '\n';
                             next = reader.Read())
                        {
                            ;
                        }
                        continue;
                    }
                    else if (next == '*')
                    {
                        reader.Read();
                        for (next = reader.Read(); next != -1; next = reader.Read())
                        {
                            if (next == '*' && reader.Peek() == '/')
                            {
                                reader.Read();
                                goto end;
                            }
                        }
end:
                        continue;
                    }
                }

                // HEXBYTES are flagged by the parser otherwise it is
                // impossible to figure them out
                if (in_byte_array)
                {
                    string hx = String.Empty;

                    if (Char.IsWhiteSpace((char)ch))
                    {
                        continue;
                    }

                    if (ch == ')')
                    {
                        res = ILToken.CloseParens;
                        break;
                    }

                    if (!is_hex(ch))
                    {
                        throw new ILTokenizingException(reader.Location, ((char)ch).ToString());
                    }
                    hx += (char)ch;
                    if (is_hex(reader.Peek()))
                    {
                        hx += (char)reader.Read();
                    }
                    else if (!Char.IsWhiteSpace((char)reader.Peek()) && reader.Peek() != ')')
                    {
                        throw new ILTokenizingException(reader.Location,
                                                        ((char)reader.Peek()).ToString());
                    }
                    res.token = Token.HEXBYTE;
                    res.val   = Byte.Parse(hx, NumberStyles.HexNumber);

                    while (Char.IsWhiteSpace((char)reader.Peek()))
                    {
                        reader.Read();
                    }
                    break;
                }

                // Ellipsis
                if (ch == '.' && reader.Peek() == '.')
                {
                    reader.MarkLocation();
                    int ch2 = reader.Read();
                    if (reader.Peek() == '.')
                    {
                        res = ILToken.Ellipsis;
                        reader.Read();
                        break;
                    }
                    reader.Unread(ch2);
                    reader.RestoreLocation();
                }

                if (ch == '.' || ch == '#')
                {
                    next = reader.Peek();
                    if (ch == '.' && Char.IsDigit((char)next))
                    {
                        numBuilder.Start(ch);
                        reader.Unread(ch);
                        numBuilder.Build();
                        if (numBuilder.ResultToken != ILToken.Invalid)
                        {
                            res.CopyFrom(numBuilder.ResultToken);
                            break;
                        }
                    }
                    else
                    {
                        if (strBuilder.Start(next) && strBuilder.TokenId == Token.ID)
                        {
                            reader.MarkLocation();
                            string dirBody = strBuilder.Build();
                            string dir     = new string ((char)ch, 1) + dirBody;
                            if (IsDirective(dir))
                            {
                                res = ILTables.Directives [dir] as ILToken;
                            }
                            else
                            {
                                reader.Unread(dirBody.ToCharArray());
                                reader.RestoreLocation();
                                res = ILToken.Dot;
                            }
                        }
                        else
                        {
                            res = ILToken.Dot;
                        }
                        break;
                    }
                }

                // Numbers && Hexbytes
                if (numBuilder.Start(ch))
                {
                    if ((ch == '-') && !(Char.IsDigit((char)reader.Peek())))
                    {
                        res = ILToken.Dash;
                        break;
                    }
                    else
                    {
                        reader.Unread(ch);
                        numBuilder.Build();
                        if (numBuilder.ResultToken != ILToken.Invalid)
                        {
                            res.CopyFrom(numBuilder.ResultToken);
                            break;
                        }
                    }
                }

                // Punctuation
                ILToken punct = ILToken.GetPunctuation(ch);
                if (punct != null)
                {
                    if (punct == ILToken.Colon && reader.Peek() == ':')
                    {
                        reader.Read();
                        res = ILToken.DoubleColon;
                    }
                    else
                    {
                        res = punct;
                    }
                    break;
                }

                // ID | QSTRING | SQSTRING | INSTR_* | KEYWORD
                if (strBuilder.Start(ch))
                {
                    reader.Unread(ch);
                    string val = strBuilder.Build();
                    if (strBuilder.TokenId == Token.ID)
                    {
                        ILToken opcode;
                        next = reader.Peek();
                        if (next == '.')
                        {
                            reader.MarkLocation();
                            reader.Read();
                            next = reader.Peek();
                            if (IsIdChar((char)next))
                            {
                                string opTail   = BuildId();
                                string full_str = String.Format("{0}.{1}", val, opTail);
                                opcode = InstrTable.GetToken(full_str);

                                if (opcode == null)
                                {
                                    if (strBuilder.TokenId != Token.ID)
                                    {
                                        reader.Unread(opTail.ToCharArray());
                                        reader.Unread('.');
                                        reader.RestoreLocation();
                                        res.val = val;
                                    }
                                    else
                                    {
                                        res.token = Token.COMP_NAME;
                                        res.val   = full_str;
                                    }
                                    break;
                                }
                                else
                                {
                                    res = opcode;
                                    break;
                                }
                            }
                            else if (Char.IsWhiteSpace((char)next))
                            {
                                // Handle 'tail.' and 'unaligned.'
                                opcode = InstrTable.GetToken(val + ".");
                                if (opcode != null)
                                {
                                    res = opcode;
                                    break;
                                }
                                // Let the parser handle the dot
                                reader.Unread('.');
                            }
                        }
                        opcode = InstrTable.GetToken(val);
                        if (opcode != null)
                        {
                            res = opcode;
                            break;
                        }
                        if (IsKeyword(val))
                        {
                            res = ILTables.Keywords [val] as ILToken;
                            break;
                        }
                    }

                    res.token = strBuilder.TokenId;
                    res.val   = val;
                    break;
                }
            }

            OnNewToken(res);
            lastToken.CopyFrom(res);
            return(res);
        }