-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 090dc27
Showing
12 changed files
with
1,353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
## C++ Version of https://ruslanspivak.com/lsbasi-part1/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <string> | ||
#include <cctype> | ||
#include <stdexcept> | ||
#include <iostream> | ||
|
||
namespace lsbasi { | ||
|
||
enum TokenType { | ||
_INTEGER, | ||
_PLUS, | ||
_EOF | ||
}; | ||
|
||
class Token{ | ||
public: | ||
TokenType type; | ||
char value; | ||
Token(TokenType type, char value): type(type), value(value){} | ||
}; | ||
|
||
class Interpreter { | ||
|
||
private: | ||
|
||
std::string text; | ||
int pos; | ||
Token * current_token; | ||
|
||
int error(){ | ||
throw std::runtime_error("Error parsing input"); | ||
} | ||
|
||
Token * get_next_token(){ | ||
|
||
if (pos > text.size() - 1) | ||
return new Token(_EOF, 0); | ||
|
||
char current_char = text[pos]; | ||
|
||
if (std::isdigit(current_char)){ | ||
pos++; | ||
return new Token (_INTEGER, current_char); | ||
} | ||
|
||
if (current_char == '+'){ | ||
pos++; | ||
return new Token (_PLUS, current_char); | ||
} | ||
|
||
error(); | ||
|
||
} | ||
|
||
void eat (TokenType type){ | ||
if (current_token->type == type) | ||
current_token = get_next_token(); | ||
else | ||
error(); | ||
} | ||
|
||
|
||
public: | ||
|
||
Interpreter(std::string text): text(text), pos(0), current_token(NULL){} | ||
|
||
int expr(){ | ||
|
||
current_token = get_next_token(); | ||
Token * left = current_token; | ||
eat(_INTEGER); | ||
|
||
Token * op = current_token; | ||
eat(_PLUS); | ||
|
||
Token * right = current_token; | ||
eat(_INTEGER); | ||
|
||
int result = (left->value - '0') + (right->value - '0'); | ||
|
||
delete right; | ||
delete op; | ||
delete left; | ||
|
||
return result; | ||
} | ||
|
||
}; | ||
|
||
}; | ||
|
||
int main (){ | ||
|
||
while(true){ | ||
|
||
std::string text; | ||
std::cout << "calc> "; | ||
std::cin >> text; | ||
lsbasi::Interpreter interpreter(text); | ||
std::cout << interpreter.expr() << std::endl; | ||
|
||
//ctrl+c to exit | ||
|
||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#include <string> | ||
#include <cctype> | ||
#include <stdexcept> | ||
#include <iostream> | ||
|
||
namespace lsbasi { | ||
|
||
enum TokenType { | ||
_INTEGER, | ||
_PLUS, | ||
_MINUS, | ||
_EOF | ||
}; | ||
|
||
class Token{ | ||
public: | ||
TokenType type; | ||
std::string value; | ||
Token(TokenType type, std::string value): type(type), value(value){} | ||
}; | ||
|
||
class Interpreter { | ||
|
||
private: | ||
|
||
std::string text; | ||
int pos; | ||
Token * current_token; | ||
char current_char; | ||
|
||
int error () { | ||
throw std::runtime_error("Error parsing input"); | ||
} | ||
|
||
void advance () { | ||
pos++; | ||
if (pos > text.size() - 1) | ||
current_char = 0; | ||
else | ||
current_char = text[pos]; | ||
} | ||
|
||
void skip_whitespace () { | ||
while((current_char != 0) && (current_char == ' ')) | ||
advance(); | ||
} | ||
|
||
std::string integer () { | ||
std::string result; | ||
while((current_char != 0) && std::isdigit(current_char)){ | ||
result += current_char; | ||
advance(); | ||
} | ||
return result; | ||
} | ||
|
||
Token * get_next_token () { | ||
|
||
while(current_char != 0){ | ||
skip_whitespace(); | ||
if (std::isdigit(current_char)) | ||
return new Token(_INTEGER, integer()); | ||
|
||
if (current_char == '+'){ | ||
advance(); | ||
return new Token (_PLUS, "+"); | ||
} | ||
|
||
if (current_char == '-'){ | ||
advance(); | ||
return new Token (_MINUS, "-"); | ||
} | ||
|
||
error(); | ||
|
||
} | ||
|
||
} | ||
|
||
void eat (TokenType type){ | ||
if (current_token->type == type) | ||
current_token = get_next_token(); | ||
else | ||
error(); | ||
} | ||
|
||
|
||
public: | ||
|
||
Interpreter(std::string text): text(text), pos(0), current_token(NULL), current_char(text[pos]) {} | ||
|
||
int expr(){ | ||
|
||
int result; | ||
|
||
current_token = get_next_token(); | ||
Token * left = current_token; | ||
eat(_INTEGER); | ||
|
||
Token * op = current_token; | ||
if (op->type == _PLUS) | ||
eat(_PLUS); | ||
else | ||
eat(_MINUS); | ||
|
||
Token * right = current_token; | ||
eat(_INTEGER); | ||
|
||
if(op->type == _PLUS) | ||
result = std::stoi(left->value) + std::stoi(right->value); | ||
else | ||
result = std::stoi(left->value) - std::stoi(right->value); | ||
|
||
delete right; | ||
delete op; | ||
delete left; | ||
|
||
return result; | ||
} | ||
|
||
}; | ||
|
||
}; | ||
|
||
int main (){ | ||
|
||
while(true){ | ||
|
||
std::string text; | ||
std::cout << "calc> "; | ||
std::cin >> text; | ||
lsbasi::Interpreter interpreter(text); | ||
std::cout << interpreter.expr() << std::endl; | ||
|
||
//ctrl+c to exit | ||
|
||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#include <string> | ||
#include <cctype> | ||
#include <stdexcept> | ||
#include <iostream> | ||
|
||
namespace lsbasi { | ||
|
||
enum TokenType { | ||
_INTEGER, | ||
_PLUS, | ||
_MINUS, | ||
_EOF | ||
}; | ||
|
||
class Token{ | ||
public: | ||
TokenType type; | ||
std::string value; | ||
Token(TokenType type, std::string value): type(type), value(value){} | ||
}; | ||
|
||
class Interpreter { | ||
|
||
private: | ||
|
||
std::string text; | ||
int pos; | ||
Token * current_token; | ||
char current_char; | ||
|
||
int error () { | ||
throw std::runtime_error("Error parsing input"); | ||
} | ||
|
||
void advance () { | ||
pos++; | ||
if (pos > text.size() - 1) | ||
current_char = 0; | ||
else | ||
current_char = text[pos]; | ||
} | ||
|
||
void skip_whitespace () { | ||
while((current_char != 0) && (current_char == ' ')) | ||
advance(); | ||
} | ||
|
||
std::string integer () { | ||
std::string result; | ||
while((current_char != 0) && std::isdigit(current_char)){ | ||
result += current_char; | ||
advance(); | ||
} | ||
return result; | ||
} | ||
|
||
Token * get_next_token () { | ||
|
||
while(current_char != 0){ | ||
skip_whitespace(); | ||
if (std::isdigit(current_char)) | ||
return new Token (_INTEGER, integer()); | ||
|
||
if (current_char == '+'){ | ||
advance(); | ||
return new Token (_PLUS, "+"); | ||
} | ||
|
||
if (current_char == '-'){ | ||
advance(); | ||
return new Token (_MINUS, "-"); | ||
} | ||
|
||
error(); | ||
|
||
} | ||
|
||
return new Token(_EOF, ""); | ||
|
||
} | ||
|
||
void eat (TokenType type){ | ||
if (current_token->type == type){ | ||
delete current_token; | ||
current_token = get_next_token(); | ||
}else | ||
error(); | ||
} | ||
|
||
int term(){ | ||
std::string res = current_token->value; | ||
eat(_INTEGER); | ||
return std::stoi(res); | ||
} | ||
|
||
|
||
public: | ||
|
||
Interpreter(std::string text): text(text), pos(0), current_token(NULL), current_char(text[pos]) {} | ||
|
||
int expr(){ | ||
|
||
current_token = get_next_token(); | ||
|
||
int result = term(); | ||
|
||
while((current_token->type == _PLUS) || (current_token->type == _MINUS)){ | ||
|
||
Token * tk = current_token; | ||
if (tk->type == _PLUS){ | ||
eat(_PLUS); | ||
result += term(); | ||
} | ||
if (tk->type == _MINUS){ | ||
eat(_MINUS); | ||
result -= term(); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
}; | ||
|
||
}; | ||
|
||
int main (){ | ||
|
||
while(true){ | ||
|
||
std::string text; | ||
std::cout << "calc> "; | ||
std::cin >> text; | ||
lsbasi::Interpreter interpreter(text); | ||
std::cout << interpreter.expr() << std::endl; | ||
|
||
//ctrl+c to exit | ||
|
||
} | ||
|
||
return 0; | ||
} |
Oops, something went wrong.