diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-09-21 14:05:50 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-09-21 14:05:50 (GMT) |
| commit | 939a04d3c77bf9aa8d54e912f5e12817de51756c (patch) | |
| tree | 750119bf74b8fbcb409eaf02d03877c00056613d /src/pim/Scanner.cpp | |
| parent | 6e44ebc358d1206c147f514225373da07b43c015 (diff) | |
| download | powder-939a04d3c77bf9aa8d54e912f5e12817de51756c.zip powder-939a04d3c77bf9aa8d54e912f5e12817de51756c.tar.gz | |
Testing new vm/language WIP
Diffstat (limited to 'src/pim/Scanner.cpp')
| -rw-r--r-- | src/pim/Scanner.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/pim/Scanner.cpp b/src/pim/Scanner.cpp new file mode 100644 index 0000000..32e64d0 --- /dev/null +++ b/src/pim/Scanner.cpp @@ -0,0 +1,178 @@ +//Lexical analyser +#include <algorithm> +#include "Scanner.h" + +namespace pim +{ + namespace compiler + { + Scanner::Scanner(std::stringstream & source_) : + source(source_) + { + nextCharacter(); + } + + Token Scanner::NextToken() + { + //Read whitespace, newlines and comments + while( + cChar == ' ' || cChar == '\t' || + cChar == '\r' || cChar == '\n' || + cChar == '/') + { + if(cChar == '/') + { + nextCharacter(); + if(cChar == '/') + { + while(cChar != '\n' && cChar != '\r') + nextCharacter(); + } + else + return Token(Token::DivideSymbol, "/", cLine); + } + + if(cChar == '\r') + { + nextCharacter(); + if(cChar == '\n') + cLine++; + else + continue; + } + else if(cChar == '\n') + cLine++; + + nextCharacter(); + } + + if(std::isalpha(cChar)) //Read alphanumeric symbols + { + cToken.clear(); + while(std::isalpha(cChar) || std::isdigit(cChar)) + { + cToken.push_back(cChar); + nextCharacter(); + } + + std::transform(cToken.begin(), cToken.end(), cToken.begin(), ::tolower); + + for(int i = 0; i < Token::SymbolNumber; i++) + if(Token::SymbolNames[i] == cToken) + return Token(i, cToken, cLine); + return Token(Token::Identifier, cToken, cLine); + } + else if(std::isdigit(cChar)) //Read numeric constants + { + bool decimal = false; + cToken.clear(); + while(std::isdigit(cChar)) + { + cToken.push_back(cChar); + nextCharacter(); + } + if(cChar == '.') + { + decimal = true; + cToken.push_back(cChar); + nextCharacter(); + while(std::isdigit(cChar)) + { + cToken.push_back(cChar); + nextCharacter(); + } + } + if(decimal) + return Token(Token::DecimalConstant, cToken, cLine); + return Token(Token::IntegerConstant, cToken, cLine); + } + else if(cChar == '=') + { + nextCharacter(); + if(cChar == '=') + { + nextCharacter(); + return Token(Token::EqualSymbol, "==", cLine); + } + return Token(Token::AssignSymbol, "=", cLine); + } + else if(cChar == '!') + { + nextCharacter(); + if(cChar == '=') + return Token(Token::NotEqualSymbol, "==", cLine); + } + else if(cChar == '(') + { + nextCharacter(); + return Token(Token::LeftBracket, "(", cLine); + } + else if(cChar == ')') + { + nextCharacter(); + return Token(Token::RightBracket, ")", cLine); + } + else if(cChar == '/') + { + nextCharacter(); + return Token(Token::DivideSymbol, "/", cLine); + } + else if(cChar == '*') + { + nextCharacter(); + return Token(Token::MultiplySymbol, "*", cLine); + } + else if(cChar == '+') + { + nextCharacter(); + return Token(Token::PlusSymbol, "+", cLine); + } + else if(cChar == '-') + { + nextCharacter(); + return Token(Token::MinusSymbol, "-", cLine); + } + else if(cChar == '%') + { + nextCharacter(); + return Token(Token::ModuloSymbol, "%", cLine); + } + else if(cChar == '<') + { + nextCharacter(); + if(cChar == '=') + { + return Token(Token::LessEqualSymbol, "<=", cLine); + } + return Token(Token::LessSymbol, "<", cLine); + } + else if(cChar == '>') + { + nextCharacter(); + if(cChar == '=') + { + return Token(Token::GreaterEqualSymbol, ">=", cLine); + } + return Token(Token::GreaterSymbol, ">", cLine); + } + else if(cChar == ',') + { + nextCharacter(); + return Token(Token::CommaSymbol, ",", cLine); + } + else + { + nextCharacter(); + return Token(Token::InvalidSymbol, std::string(1, cChar), cLine); + } + } + + void Scanner::nextCharacter() + { + if(source.good()) + cChar = source.get(); + else + cChar = 0; + } + } +}
\ No newline at end of file |
