Exemplo n.º 1
0
        public Token NextToken(bool skipEol = false)
        {
            // игнорируемые разделители
            while (Ch == ' ' || Ch == '\t' || (skipEol && Ch == '\n'))
                NextCh();

            if (Ch == '/' && Commnet0() || Ch == '/' && Commnet1() || Ch == ';' && Commnet2()) return NextToken(skipEol);
            if (Eof) return new Token { Position = Pos, Type = TokenType.EndFile };

            if (Ch == '\n')
            {
                NextCh();
                return new Token {Position = Pos, Type = TokenType.EndLine};
            }

            _tokVal.Length = 0;
            if (Col == 1) return GetLabel();
            if (Ch == '"') return GetString(true);
            if (Ch == '\'') return GetString(false);
            //if (char.IsDigit(Ch) || Ch == '#' || Ch == '$' || Ch == '%') return GetNumber();
            if (char.IsDigit(Ch) || Ch == '#' || Ch == '%') return GetNumber();

            if (Ch == '.')
            {
                NextCh();
                if (char.IsLetter(Ch))
                    return GetIdentifier();

                return new Token {Position = Pos, Type = TokenType.Repeat};
            }

            if (char.IsLetter(Ch) || Ch == '_') return GetIdentifier();

            var res = new Token {Position = Pos};
            switch (Ch)
            {
                case '!':
                    NextCh();
                    if (Ch == '=')
                    {
                        NextCh();
                        res.Type = TokenType.NotEqual;
                        break;
                    }
                    res.Type = TokenType.LogicalNot;
                    break;

                case '~':
                    NextCh();
                    res.Type = TokenType.Complement;
                    break;

                case '+':
                    NextCh();
                    res.Type = TokenType.Plus;
                    break;

                case '-':
                    NextCh();
                    res.Type = TokenType.Minus;
                    break;

                case '*':
                    NextCh();
                    res.Type = TokenType.Mul;
                    break;

                case '/':
                    NextCh();
                    res.Type = TokenType.Div;
                    break;

                case '%':
                    NextCh();
                    res.Type = TokenType.Mod;
                    break;

                case '<':
                    NextCh();
                    switch (Ch)
                    {
                        case '<': // <<
                            NextCh();
                            res.Type = TokenType.ShiftLeft;
                            break;
                        case '=': // <=
                            NextCh();
                            res.Type = TokenType.LessOrEqual;
                            break;
                        case '?': // <?
                            NextCh();
                            res.Type = TokenType.Minimum;
                            break;
                        default: // <
                            res.Type = TokenType.Less;
                            break;
                    }
                    break;

                case '>':
                    NextCh();
                    switch (Ch)
                    {
                        case '>':
                            NextCh();
                            if (Ch == '>') // >>>
                            {
                                NextCh();
                                res.Type = TokenType.UnsignedShiftRight;
                                break;
                            }
                            res.Type = TokenType.ShiftRight; // >>
                            break;
                        case '?': // >?
                            NextCh();
                            res.Type = TokenType.Maximum;
                            break;
                        case '=': // >=
                            NextCh();
                            res.Type = TokenType.GreaterOrEqual;
                            break;
                        default: // >
                            res.Type = TokenType.Greater;
                            break;
                    }
                    break;

                case '=':
                    NextCh(); // =
                    if (Ch == '=') NextCh(); // ==
                    res.Type = TokenType.Equal;
                    break;

                case '&':
                    NextCh();
                    if (Ch == '&') // &&
                    {
                        NextCh();
                        res.Type = TokenType.LogicalAnd;
                        break;
                    }
                    res.Type = TokenType.BitAnd; // &
                    break;

                case '|':
                    NextCh();
                    if (Ch == '|') // ||
                    {
                        NextCh();
                        res.Type = TokenType.LogicalOr;
                        break;
                    }
                    res.Type = TokenType.BitOr; // |
                    break;

                case '^':
                    NextCh();
                    res.Type = TokenType.BitXor;
                    break;

                case '(':
                    NextCh();
                    res.Type = TokenType.LParam;
                    break;

                case ')':
                    NextCh();
                    res.Type = TokenType.RParam;
                    break;

                case '[':
                    NextCh();
                    res.Type = TokenType.LIndex;
                    break;

                case ']':
                    NextCh();
                    res.Type = TokenType.RIndex;
                    break;

                case '$':
                    NextCh();
                    if (Ch == '$') // $$
                    {
                        NextCh();
                        res.Type = TokenType.CurrentPage;
                        break;
                    }
                    if (char.IsDigit(Ch) || IsHexLetter(Ch))
                        return GetHexNumber(res.Position); // hex Число

                    res.Type = TokenType.CurrentPc; // $
                    break;

                case '#':
                    NextCh();
                    if (Ch == '#') // ##
                    {
                        NextCh();
                        res.Type = TokenType.DefaultAlign;
                        break;
                    }
                    res.Type = TokenType.NextAlign; // #
                    break;

                case ':':
                    NextCh();
                    res.Type = TokenType.Colon;
                    break;

                case ',':
                    NextCh();
                    res.Type = TokenType.Comma;
                    break;

                default:
                    throw new ApplicationException("неожиданый символ");
            }

            return res;
        }
Exemplo n.º 2
0
        private Token GetNumber()
        {
            var startpos = Pos;
            var firstCh = Ch;
            var binOnly = true;
            var octOnly = true;

            if (Ch == '$' || Ch == '#')
            {
                NextCh();
                return GetHexNumber(startpos);
            }

            if (Ch == '%')
            {
                NextCh();
                return GetBinNumber(startpos);
            }

            if (Ch == '0' && IsChar('x'))
            {
                NextCh();
                NextCh();
                return GetHexNumber(startpos);
            }

            var c = GetCh() ?? (char)0;
            if ( Ch == '0' && IsHexLetter(c))
            {
                NextCh();
                return GetHexNumber(startpos);
            }

            var res = new Token {Position = startpos, Type = TokenType.Number};

            while (!Eof)
            {
                var tmp = GetCh() ?? (char)0;
                var last = ((!char.IsLetter(tmp) && !char.IsDigit(tmp)) || IsWs(tmp));

                if (IsHexLetter(Ch))
                {
                    if (firstCh == '0') return GetHexNumber(startpos);
                    if (!last) return GetHexNumber(startpos);
                }

                if (char.IsDigit(Ch))
                {
                    if (Ch > '1') binOnly = false;
                    if (Ch > '7') octOnly = false;

                    AddChar();
                    continue;
                }

                var t = char.ToLower(Ch);

                if (t == 'b' && binOnly && firstCh == '1')
                {
                    NextCh();
                    res.Modifer = "bin";
                    res.Value = _tokVal.ToString();

                    //NextCh();
                    if (!char.IsLetter(Ch) || IsWs()) return res;
                }

                if (t == 'h')
                {
                    NextCh();
                    res.Modifer = "hex";
                    res.Value = _tokVal.ToString();

                    //NextCh();
                    if (!char.IsLetter(Ch) || IsWs()) return res;
                }

                if ((t=='o' || t=='q') && octOnly)
                {
                    NextCh();
                    res.Modifer = "oct";
                    res.Value = _tokVal.ToString();

                    //NextCh();
                    if (!char.IsLetter(Ch) || IsWs()) return res;
                }

                if (t == 'd'|| IsWs() || !char.IsLetter(Ch)) // если d в конце либо пробел было символ то число ок
                {
                    res.Modifer = "dec";
                    res.Value = _tokVal.ToString();

                    if (t == 'd') // проверим что после d все ок
                    {
                        NextCh();
                        if (!char.IsLetter(Ch) || IsWs()) return res;
                    }
                    else
                        return res;
                }

                AddChar();
                throw new ApplicationException($"Неверный символ в числе \"{_tokVal}\", в позиции {Pos}");
            }

            throw new ApplicationException("Неожиданный конец файла");
        }
Exemplo n.º 3
0
        private Token GetBinNumber(Position startPos)
        {
            var res = new Token {Position = startPos, Type = TokenType.Number, Modifer = "bin"};

            AddChar();

            while (!Eof)
            {
                if (Ch == '0' || Ch == '1')
                {
                    AddChar();
                    continue;
                }

                if (Ch == 'b' || Ch == 'B')
                {
                    NextCh();
                    break;
                }

                // если следом за числом идет пробел или не буква то ок
                if (!char.IsLetter(Ch) || IsWs()) break;

                throw new ApplicationException($"Неверный символ в Bin числе, в позиции {Pos}");
            }

            res.Value = _tokVal.ToString();
            return res;
        }
Exemplo n.º 4
0
        private Token GetHexNumber(Position startPos)
        {
            var res = new Token {Position = startPos, Type = TokenType.Number, Modifer = "hex"};

            AddChar();

            while (!Eof)
            {
                if (char.IsDigit(Ch) || IsHexLetter(Ch))
                {
                    AddChar();
                    continue;
                }

                if (Ch == 'h' || Ch == 'H')
                {
                    NextCh();
                    res.Value = _tokVal.ToString();
                    break;
                }

                // если следом за числом идет пробел или не буква то ок
                if (!char.IsLetter(Ch) || IsWs()) break;

                AddChar();
                throw new ApplicationException($"Неверный символ в Hex числе \"{_tokVal}\" в позиции {Pos.Line}:{Pos.Col}");
            }

            res.Value = _tokVal.ToString();
            return res;
        }
Exemplo n.º 5
0
 protected void NextToken()
 {
     Token = _scanner.NextToken();
 }