public void Match(TokenTypeDefinition t) { if (t == this.CurrentToken.TokenTypeDefinition) { Advance(); } else { this.LogErrorToken(new Token(TokenCategory.Literal, t, "")); } }
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); }
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); }
//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; }
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())); }