void Lexer::makeCharLiteral() { if (location.ptr + 4 >= eof) { storeToken(Token::Eof); return; } location.stepColumn(); char c = *location.ptr; location.stepColumn(); char d = *location.ptr; if (d == '\'') { Token token(Token::Char, c); storeToken(token, location); } else if (c == '\\') { switch (d) { case 'n': c = '\n'; break; default: storeToken(Token::Invalid); break; } Token token(Token::Char, c); storeToken(token, location); location.stepColumn(); } else { storeToken(Token::Invalid); } location.stepColumn(); }
void Lexer::makeIdentifierOrKeywordToken(const char* tStart, const char* tEnd) { std::string str(tStart, tEnd); KeywordMap::const_iterator it = keywordMap.find(str); if (it == keywordMap.end()) { Token token(Token::Identifier, str); storeToken(token, start); } else { Token token(it->second, str); storeToken(token, start); } }
int main(void) { precedence token; stack[0] = eos; int isp[] = {0,19,12,12,13,13,13,0}; int icp[] = {20,19,12,12,13,13,13,0}; FILE *fptr; /*Get information from file*/ fptr = fopen("set2.txt", "r"); if(!fptr){ printf("Open failure!"); exit(1); } while(fgets(expr, 45, fptr) != NULL){ printf("Infix expresion: %s", expr); } printf("\n"); fclose(fptr); /*從右至左scan*/ while(expr[i] != '\0') i++; for(token = getToken(); i >= 0; token = getToken()){ if(token == operand) pref[j++] = symbol; else if(token == lparen){ while(stack[top] != rparen) storeToken(pop()); pop(); } else{ while(isp[stack[top]] > icp[token]) storeToken(pop()); push(token); } } /*處理剩下operators*/ while((token = pop()) != eos) storeToken(token); /*倒著印出Prefix*/ printf("Prifix expresion: "); for(j--; j >= 0; j--) printf("%c", pref[j]); getchar(); return 0; }
void Lexer::makeStringLiteral(const char* tStart) { start = location; location.stepColumn(); while (location.ptr < eof) { char c = *location.ptr; switch (c) { case '\n': storeToken(Token::Invalid); break; case '"': { Token token(Token::String, tStart + 1, location.ptr); storeToken(token, start); location.stepColumn(); return; } default: break; } location.stepColumn(); } storeToken(Token::Eof); }
void Lexer::storePreviousToken() { switch (state) { case GettingIdentifier: if (location.ptr - start.ptr == 1 && *(start.ptr) == '_') { makeOperatorToken(start); } else { makeIdentifierOrKeywordToken(start.ptr, location.ptr); } break; case GettingIntegerNumber: { Token token(Token::Integer, start.ptr, location.ptr); storeToken(token, start); break; } case GettingFloatingPointNumber: { Token token(Token::Float, start.ptr, location.ptr); storeToken(token, start); break; } default: break; } }
void Lexer::tokenize() { while (location.ptr < eof) { bool newLine = false; char c = *location.ptr; switch (c) { case ' ': case '\t': case '\r': storePreviousToken(); break; case '\n': newLine = true; storePreviousToken(); storeToken(Token::Newline); break; 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 '_': switch (state) { case Idle: state = GettingIdentifier; start = location; break; case GettingIntegerNumber: case GettingFloatingPointNumber: storeToken(Token::Invalid); break; default: break; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': switch (state) { case Idle: state = GettingIntegerNumber; start = location; break; default: break; } break; case '/': storePreviousToken(); if (isNextChar('/', location.ptr)) { skipUntilNewline(); continue; } else if (isNextChar('*', location.ptr)) { skipMultilineComment(); continue; } else { makeOperatorToken(location); } break; case '=': case '!': case '+': case '-': case '*': case '%': case '.': case ',': case '>': case '<': case ':': case ';': case '?': case '|': case '&': case '^': case '~': case '(': case ')': case '{': case '}': case '[': case ']': if (c == '.' && !isNextChar('.') && state == GettingIntegerNumber) { state = GettingFloatingPointNumber; } else { storePreviousToken(); makeOperatorToken(location); } break; case '"': storePreviousToken(); makeStringLiteral(location.ptr); continue; case '\'': storePreviousToken(); makeCharLiteral(); continue; default: storeToken(Token::Invalid); break; } if (newLine) { location.stepLine(); } else { location.stepColumn(); } } storeToken(Token::Eof); }
void Lexer::makeOperatorToken(const Location& startLocation) { Operator::Kind op; const char* tStart = startLocation.ptr; switch (*tStart) { case '=': if (isNextChar('=', tStart)) { op = Operator::Equal; location.stepColumn(); } else { op = Operator::Assignment; } break; case '!': if (isNextChar('=', tStart)) { op = Operator::NotEqual; location.stepColumn(); } else { op = Operator::LogicalNegation; } break; case ':': if (isNextChar('=', tStart)) { op = Operator::AssignmentExpression; location.stepColumn(); } else { op = Operator::Colon; } break; case '>': if (isNextChar('=', tStart)) { op = Operator::GreaterOrEqual; location.stepColumn(); } else if (isNextChar('>', tStart)) { op = Operator::RightShift; location.stepColumn(); } else { op = Operator::Greater; } break; case '<': if (isNextChar('=', tStart)) { op = Operator::LessOrEqual; location.stepColumn(); } else if (isNextChar('<', tStart)) { op = Operator::LeftShift; location.stepColumn(); } else { op = Operator::Less; } break; case '&': if (isNextChar('&', tStart)) { op = Operator::LogicalAnd; location.stepColumn(); } else { op = Operator::BitwiseAnd; } break; case '|': if (isNextChar('|', tStart)) { op = Operator::LogicalOr; location.stepColumn(); } else { op = Operator::BitwiseOr; } break; case '+': if (isNextChar('+', tStart)) { op = Operator::Increment; location.stepColumn(); } else if (isNextChar('=', tStart)) { op = Operator::AdditionAssignment; location.stepColumn(); } else { op = Operator::Addition; } break; case '-': if (isNextChar('-', tStart)) { op = Operator::Decrement; location.stepColumn(); } else if (isNextChar('=', tStart)) { op = Operator::SubtractionAssignment; location.stepColumn(); } else if (isNextChar('>', tStart)) { op = Operator::Arrow; location.stepColumn(); } else { op = Operator::Subtraction; } break; case '*': if (isNextChar('=', tStart)) { op = Operator::MultiplicationAssignment; location.stepColumn(); } else { op = Operator::Multiplication; } break; case '/': if (isNextChar('=', tStart)) { op = Operator::DivisionAssignment; location.stepColumn(); } else { op = Operator::Division; } break; case '.': if (isNextChar('.', tStart)) { if (isNextChar('.', tStart + 1)) { op = Operator::Range; location.stepColumn(); } else { op = Operator::Wildcard; } location.stepColumn(); } else { op = Operator::Dot; } break; case '%': op = Operator::Modulo; break; case ',': op = Operator::Comma; break; case '(': op = Operator::OpenParentheses; break; case ')': op = Operator::CloseParentheses; break; case '{': op = Operator::OpenBrace; break; case '}': op = Operator::CloseBrace; break; case '[': op = Operator::OpenBracket; break; case ']': op = Operator::CloseBracket; break; case ';': op = Operator::Semicolon; break; case '?': op = Operator::Question; break; case '_': op = Operator::Placeholder; break; case '^': op = Operator::BitwiseXor; break; case '~': op = Operator::BitwiseNot; break; default: break; } Token token(op); storeToken(token, startLocation); }
void Lexer::storeToken(Token::Kind kind) { Token token(kind); storeToken(token, location); }