mirror of
https://github.com/bigsketti/ProfaneC.git
synced 2024-12-25 15:10:27 +00:00
Initial commit, only the lexer as of now.
This commit is contained in:
commit
e6ae86f673
5 changed files with 224 additions and 0 deletions
63
headers/lexer.h
Normal file
63
headers/lexer.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#ifndef LEXER_H
|
||||||
|
#define LEXER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//list of keywords
|
||||||
|
enum class Keywords {
|
||||||
|
identifier,
|
||||||
|
integer,
|
||||||
|
floatpnt,
|
||||||
|
string,
|
||||||
|
character,
|
||||||
|
boolean,
|
||||||
|
plus,
|
||||||
|
minus,
|
||||||
|
multiply,
|
||||||
|
divide,
|
||||||
|
l_Paren,
|
||||||
|
r_Paren,
|
||||||
|
l_Brace,
|
||||||
|
r_Brace,
|
||||||
|
l_Brack,
|
||||||
|
r_Brack,
|
||||||
|
semicolon,
|
||||||
|
end_of_file,
|
||||||
|
unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Token {
|
||||||
|
Keywords type;
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
|
||||||
|
Token(Keywords type, std::string value) : type(type), value(value) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Lexer {
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string stringInput;
|
||||||
|
int position;
|
||||||
|
char currentChar;
|
||||||
|
|
||||||
|
//advances position in the input string
|
||||||
|
void nextPosition();
|
||||||
|
|
||||||
|
void skipWhiteSpace();
|
||||||
|
|
||||||
|
//handles integer literals
|
||||||
|
Token number();
|
||||||
|
|
||||||
|
//handles identifiers
|
||||||
|
Token identifier();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Lexer(const std::string &input);
|
||||||
|
|
||||||
|
Token getNextToken();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
BIN
profaneCompiler
Executable file
BIN
profaneCompiler
Executable file
Binary file not shown.
110
src/lexer.cpp
Normal file
110
src/lexer.cpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#include "/home/mason/code-shit/ProfaneC/headers/lexer.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void Lexer::nextPosition() {
|
||||||
|
position++;
|
||||||
|
|
||||||
|
if(position < stringInput.size()) {
|
||||||
|
currentChar = stringInput[position];
|
||||||
|
std::cout << "Advancing to: " << currentChar << " | at position: " << position << std::endl;
|
||||||
|
} else {
|
||||||
|
currentChar = '\0';
|
||||||
|
std::cout << "end of input\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lexer::skipWhiteSpace() {
|
||||||
|
if (currentChar != '\0' && std::isspace(currentChar)) {
|
||||||
|
Lexer::nextPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Token Lexer::number() {
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (currentChar != '\0' && isdigit(currentChar)) {
|
||||||
|
value += currentChar;
|
||||||
|
nextPosition();
|
||||||
|
}
|
||||||
|
return Token(Keywords::integer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Token Lexer::identifier() {
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
while (currentChar != '\0' && std::isalnum(currentChar)) {
|
||||||
|
value += currentChar;
|
||||||
|
nextPosition();
|
||||||
|
}
|
||||||
|
return Token(Keywords::identifier, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lexer::Lexer(const std::string &input) {
|
||||||
|
this->position = 0;
|
||||||
|
this->stringInput = input;
|
||||||
|
this->currentChar = stringInput[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
Token Lexer::getNextToken() {
|
||||||
|
while (currentChar != '\0') {
|
||||||
|
std::cout << currentChar << std::endl;
|
||||||
|
|
||||||
|
if (std::isspace(currentChar)) {
|
||||||
|
skipWhiteSpace();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::isdigit(currentChar)) {
|
||||||
|
return number();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::isalpha(currentChar)) {
|
||||||
|
return identifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
//this sure is ugly
|
||||||
|
switch (currentChar) {
|
||||||
|
case '+':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::plus, "+");
|
||||||
|
case '-':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::minus, "-");
|
||||||
|
case '*':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::multiply, "*");
|
||||||
|
case '/':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::divide, "/");
|
||||||
|
case '(':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::l_Paren, "(");
|
||||||
|
case ')':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::r_Paren, ")");
|
||||||
|
case '{':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::l_Brace, "{");
|
||||||
|
case '}':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::r_Brace, "}");
|
||||||
|
case '[':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::l_Brack, "[");
|
||||||
|
case ']':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::r_Brack, "]");
|
||||||
|
case ';':
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::semicolon, ";");
|
||||||
|
default:
|
||||||
|
nextPosition();
|
||||||
|
return Token(Keywords::unknown, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "EOF" << std::endl;
|
||||||
|
return Token(Keywords::end_of_file, "");
|
||||||
|
|
||||||
|
}
|
48
src/profaneCompiler.cpp
Normal file
48
src/profaneCompiler.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "/home/mason/code-shit/ProfaneC/headers/lexer.h"
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const Token& token) {
|
||||||
|
os << "Type: " << static_cast<int>(token.type) << ", Value: " << token.value;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
std::vector<Token> tokenVec;
|
||||||
|
std::ifstream file_in("/home/mason/code-shit/ProfaneC/testInput.txt");
|
||||||
|
|
||||||
|
if (file_in.is_open()) {
|
||||||
|
std::cout << "file open\n";
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (getline(file_in, line)) {
|
||||||
|
std::cout << "Reading line: " << line << std::endl;
|
||||||
|
|
||||||
|
Lexer Lexer(line);
|
||||||
|
Token token = Lexer.getNextToken();
|
||||||
|
|
||||||
|
while (token.type != Keywords::end_of_file) {
|
||||||
|
std::cout << "Token " << static_cast<int>(token.type) << " | Value: " << token.value << std::endl;
|
||||||
|
tokenVec.push_back(token);
|
||||||
|
token = Lexer.getNextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (file_in.fail()) {
|
||||||
|
std::cerr << "File read error" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_in.close();
|
||||||
|
|
||||||
|
std::cout << "printing all tokens : \n";
|
||||||
|
|
||||||
|
for (int i = 0; i < tokenVec.size(); i++) {
|
||||||
|
std::cout << tokenVec.at(i) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
3
testInput.txt
Normal file
3
testInput.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
int main() {
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue