public void Match(TokenTypeDefinition t)
 {
     if (t == this.CurrentToken.TokenTypeDefinition)
     {
         Advance();
     }
     else
     {
         this.LogErrorToken(new Token(TokenCategory.Literal, t, ""));
     }
 }
Example #2
0
        public TokenTypeValue E()
        {
            TokenTypeValue t1 = T();

            while (scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_PLUS ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_MINUS)
            {
                TokenTypeDefinition operation = scanner.CurrentToken.TokenTypeDefinition;
                scanner.Match(operation);

                TokenTypeValue t2 = T();

                t1 = Generate(t1, t2, operation);
            }

            return(t1);
        }
Example #3
0
        public TokenTypeValue T()
        {
            TokenTypeValue t1 = M();

            while (scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_SLASH ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_STAR)
            {
                TokenTypeDefinition operation = scanner.CurrentToken.TokenTypeDefinition;
                scanner.Match(operation);

                TokenTypeValue t2 = M();

                t1 = Generate(t1, t2, operation);
            }

            return(t1);
        }
Example #4
0
        //ARITHMETIC HEADACHE

        public TokenTypeValue M()
        {
            TokenTypeValue t1 = F();

            while (scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_EQUAL ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_NOTEQ ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_GTEQ ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_GREATER ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_LESS ||
                   scanner.CurrentToken.TokenTypeDefinition == TokenTypeDefinition.TK_LTEQ)
            {
                TokenTypeDefinition operation = scanner.CurrentToken.TokenTypeDefinition;
                scanner.Match(operation);

                TokenTypeValue t2 = F();

                t1 = Generate(t1, t2, operation);
            }

            return(t1);
        }
 public Token(TokenCategory symbol, TokenTypeDefinition tokenTypeDefinition, string value)
 {
     this.TokenCategory       = symbol;
     this.TokenTypeDefinition = tokenTypeDefinition;
     this.Value = value;
 }
Example #6
0
        public TokenTypeValue Generate(TokenTypeValue t1, TokenTypeValue t2, TokenTypeDefinition operation)
        {
            TokenTypeValue tokenFound = new TokenTypeValue(DataTypeDefinition.TYPE_VOID, null);

            #region plus
            if (operation == TokenTypeDefinition.TK_PLUS)
            {
                if (t1.DataType == t2.DataType)
                {
                    tokenFound.DataType = t1.DataType;
                    if (t1.DataType == DataTypeDefinition.TYPE_INT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_add);
                    }
                    else if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_fadd);
                    }
                }
                else
                {
                    tokenFound.DataType = DataTypeDefinition.TYPE_FLOAT;
                    if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fadd);
                    }
                    else
                    {
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_fadd);
                    }
                }
            }
            #endregion

            #region minus
            if (operation == TokenTypeDefinition.TK_MINUS)
            {
                if (t1.DataType == t2.DataType)
                {
                    tokenFound.DataType = t1.DataType;
                    if (t1.DataType == DataTypeDefinition.TYPE_INT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_sub);
                    }
                    else if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_sub);
                    }
                }
                else
                {
                    tokenFound.DataType = DataTypeDefinition.TYPE_FLOAT;
                    if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_sub);
                    }
                    else
                    {
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_sub);
                    }
                }
            }
            #endregion

            #region star_multiply
            if (operation == TokenTypeDefinition.TK_STAR)
            {
                if (t1.DataType == t2.DataType)
                {
                    tokenFound.DataType = t1.DataType;
                    if (t1.DataType == DataTypeDefinition.TYPE_INT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_mul);
                    }
                    else if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_fmul);
                    }
                }
                else
                {
                    tokenFound.DataType = DataTypeDefinition.TYPE_FLOAT;
                    if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fmul);
                    }
                    else
                    {
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_fmul);
                    }
                }
            }
            #endregion

            #region divide_slash
            if (operation == TokenTypeDefinition.TK_SLASH)
            {
                if (t1.DataType == t2.DataType)
                {
                    tokenFound.DataType = t1.DataType;
                    if (t1.DataType == DataTypeDefinition.TYPE_INT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_div);
                    }
                    else if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_fdiv);
                    }
                }
                else
                {
                    tokenFound.DataType = DataTypeDefinition.TYPE_FLOAT;
                    if (t1.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fdiv);
                    }
                    else
                    {
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_fdiv);
                    }
                }
            }
            #endregion



            #region relational operators
            if (operation == TokenTypeDefinition.TK_EQUAL ||
                operation == TokenTypeDefinition.TK_NOTEQ ||
                operation == TokenTypeDefinition.TK_GTEQ ||
                operation == TokenTypeDefinition.TK_GREATER ||
                operation == TokenTypeDefinition.TK_LESS ||
                operation == TokenTypeDefinition.TK_LTEQ)
            {
                tokenFound.DataType = DataTypeDefinition.TYPE_BOOL;

                if (t1.DataType != t2.DataType)
                {
                    if (t1.DataType == DataTypeDefinition.TYPE_FLOAT && t2.DataType == DataTypeDefinition.TYPE_INT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                    }
                    else if (t1.DataType == DataTypeDefinition.TYPE_INT && t2.DataType == DataTypeDefinition.TYPE_FLOAT)
                    {
                        GenerateOperation(OperationTypeDefinition.op_exch);
                        GenerateOperation(OperationTypeDefinition.op_fcon);
                        GenerateOperation(OperationTypeDefinition.op_exch);
                    }
                    else
                    {
                        scanner.LogErrorToken(new Token(TokenCategory.Identifier, TokenTypeDefinition.TK_DATATYPEMISMATCH, ""));
                    }
                }

                switch (operation)
                {
                case TokenTypeDefinition.TK_EQUAL:
                {
                    GenerateOperation(OperationTypeDefinition.op_eql);
                    break;
                }

                case TokenTypeDefinition.TK_NOTEQ:
                {
                    GenerateOperation(OperationTypeDefinition.op_neq);
                    break;
                }

                case TokenTypeDefinition.TK_GTEQ:
                {
                    GenerateOperation(OperationTypeDefinition.op_geq);
                    break;
                }

                case TokenTypeDefinition.TK_GREATER:
                {
                    GenerateOperation(OperationTypeDefinition.op_gtr);
                    break;
                }

                case TokenTypeDefinition.TK_LESS:
                {
                    GenerateOperation(OperationTypeDefinition.op_lss);
                    break;
                }

                case TokenTypeDefinition.TK_LTEQ:
                {
                    GenerateOperation(OperationTypeDefinition.op_leq);
                    break;
                }
                }
            }
            #endregion

            return(tokenFound);
        }
        public Token Advance()
        {
            EatWhitespace();

            if (IsAtEnd)
            {
                _done = true;
                return(null);
            }
            var nextChar = NextChar();

            if (Syntax.IsSymbol(nextChar))
            {
                _currentToken = ScanSymbol(nextChar);
            }
            else if (Syntax.IsLiteralStart(nextChar))
            {
                var strConst = EatWhile(c => Syntax.IsCharacterWithinWord(c, nextChar));
                NextChar();  //Remove last ' or "
                _currentToken = new Token(TokenCategory.Literal, TokenTypeDefinition.TK_CHARLIT, strConst);
            }
            else if (Syntax.IsNumber(nextChar))  //can be integer or floating value
            {
                var intConst = nextChar.ToString();
                intConst += EatWhile(Syntax.IsNumber);

                if (LookAhead() != '.')
                {
                    int result;
                    if (!int.TryParse(intConst, out result))
                    {
                        throw new CompilationException("Int const must be in range [0,2147483648), " + "but got: " + intConst, _currentLine);
                    }
                    _currentToken = new Token(TokenCategory.Digit, TokenTypeDefinition.TK_INTLIT, intConst);
                }
                else
                {
                    var floatConstant = intConst + nextChar.ToString();
                    floatConstant += EatWhile(Syntax.IsNumber);

                    float result;
                    if (!float.TryParse(intConst, out result))
                    {
                        throw new CompilationException("Float const must be in range [1.17549E-38,3.40282E38), " + "but got: " + floatConstant, _currentLine);
                    }
                    _currentToken = new Token(TokenCategory.Digit, TokenTypeDefinition.TK_REALLIT, floatConstant);
                }
            }
            else if (Syntax.IsLetter(nextChar))
            {
                var strConst = nextChar + EatWhile(c => Syntax.IsLetter(c));
                TokenTypeDefinition keywordIdentifier = KeyWordId(strConst);

                if (keywordIdentifier != TokenTypeDefinition.TK_BOOLLIT)
                {
                    _currentToken =
                        new Token(
                            (keywordIdentifier == TokenTypeDefinition.TK_ID)
                                ? TokenCategory.Identifier
                                : TokenCategory.Keyword, keywordIdentifier, strConst);
                }
                else
                {
                    _currentToken = new Token(TokenCategory.Literal, keywordIdentifier, strConst);
                }
            }
            else
            {
                LogErrorToken(_currentToken);
                //throw new CompilationException("Unexpected character: " + nextChar, _currentLine);
            }

            return(_currentToken);
        }
        private Token ScanSymbol(char sym_char)
        {
            char[] _sym_Name = new char[255];
            _sym_Name[0] = sym_char;
            char _sym_char = sym_char;
            TokenTypeDefinition _sym_Token = TokenTypeDefinition.TK_EMPTY;
            int stop = 0;

            switch (_sym_char)
            {
            case '/':
            {
                _sym_char = LookAhead();
                if (_sym_char == '/')
                {
                    while (_sym_char != '\n')
                    {
                        _sym_char = NextChar();
                    }
                }
                else if (_sym_char == '*')
                {
                    do
                    {
                        _sym_char = NextChar();
                        if (_sym_char == '\0')
                        {
                            throw new Exception("End of file reached.");
                        }
                        else if (_sym_char == '*')
                        {
                            _sym_char = NextChar();
                            if (_sym_char == '/')
                            {
                                stop = 1;
                            }
                        }
                    } while (stop == 0);
                }
                else if (_sym_char == '=')
                {
                    _sym_Token   = TokenTypeDefinition.TK_ASDIV;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_SLASH;
                }
                break;
            }

            case '!':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_NOTEQ;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_NOT;
                }
                break;
            }

            case '%':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASMOD;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_MOD;
                }
                break;
            }

            case '&':
            {
                _sym_char = LookAhead();
                if (_sym_char == '&')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_LOGAND;
                    _sym_Name[1] = _sym_char;
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASAND;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_AMPER;
                }
                break;
            }

            case '(':
            {
                _sym_Token = TokenTypeDefinition.TK_LPAREN;
                break;
            }

            case ')':
            {
                _sym_Token = TokenTypeDefinition.TK_RPAREN;
                break;
            }

            case '*':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASMUL;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_STAR;
                }
                break;
            }

            case '+':
            {
                _sym_char = LookAhead();
                if (_sym_char == '+')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_INCR;
                    _sym_Name[1] = _sym_char;
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASPLUS;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_PLUS;
                }
                break;
            }

            case ',':
            {
                _sym_Token = TokenTypeDefinition.TK_COMMA;
                break;
            }

            case '-':
            {
                _sym_char = LookAhead();
                if (_sym_char == '-')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_DECR;
                    _sym_Name[1] = _sym_char;
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASMINUS;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_MINUS;
                }
                break;
            }

            case ':':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_EQUAL;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_COLON;
                }
                break;
            }

            case ';':
            {
                _sym_Token = TokenTypeDefinition.TK_SEMI;
                break;
            }

            case '<':
            {
                _sym_char = LookAhead();
                if (_sym_char == '<')
                {
                    _sym_char    = NextChar();
                    _sym_Name[1] = _sym_char;
                    _sym_char    = LookAhead();
                    if (_sym_char == '=')
                    {
                        _sym_char    = NextChar();
                        _sym_Token   = TokenTypeDefinition.TK_ASLSHIFT;
                        _sym_Name[2] = _sym_char;
                    }
                    else
                    {
                        _sym_Token = TokenTypeDefinition.TK_LSHIFT;
                    }
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_LTEQ;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_LESS;
                }
                break;
            }

            case '=':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_EQUAL;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_ASSIGN;
                }
                break;
            }

            case '>':
            {
                _sym_char = LookAhead();
                if (_sym_char == '>')
                {
                    _sym_char    = NextChar();
                    _sym_Name[1] = _sym_char;
                    _sym_char    = LookAhead();
                    if (_sym_char == '=')
                    {
                        _sym_char    = NextChar();
                        _sym_Name[2] = _sym_char;
                        _sym_Token   = TokenTypeDefinition.TK_ASRSHIFT;
                    }
                    else
                    {
                        _sym_Token = TokenTypeDefinition.TK_RSHIFT;
                    }
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_GTEQ;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_GREATER;
                }
                break;
            }

            case '?':
            {
                _sym_Token = TokenTypeDefinition.TK_QMARK;
                break;
            }

            case '[':
            {
                _sym_Token = TokenTypeDefinition.TK_LBRACK;
                break;
            }

            case ']':
            {
                _sym_Token = TokenTypeDefinition.TK_RBRACK;
                break;
            }

            case '^':
            {
                _sym_char = LookAhead();
                if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASXOR;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_CARET;
                }
                break;
            }

            case '{':
            {
                _sym_Token = TokenTypeDefinition.TK_LBRACE;
                break;
            }

            case '}':
            {
                _sym_Token = TokenTypeDefinition.TK_RBRACE;
                break;
            }

            case '|':
            {
                _sym_char = LookAhead();
                if (_sym_char == '|')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_LOGOR;
                    _sym_Name[1] = _sym_char;
                }
                else if (_sym_char == '=')
                {
                    _sym_char    = NextChar();
                    _sym_Token   = TokenTypeDefinition.TK_ASOR;
                    _sym_Name[1] = _sym_char;
                }
                else
                {
                    _sym_Token = TokenTypeDefinition.TK_PIPE;
                }
                break;
            }
            }

            return(new Token(TokenCategory.Symbol, _sym_Token, _sym_Name.ToString()));
        }