summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exceptions.cpp8
-rw-r--r--include/exceptions.hpp11
-rw-r--r--include/lexer.hpp4
-rw-r--r--lexer.cpp21
-rw-r--r--main.cpp39
-rw-r--r--makefile4
6 files changed, 76 insertions, 11 deletions
diff --git a/exceptions.cpp b/exceptions.cpp
new file mode 100644
index 0000000..23ca88b
--- /dev/null
+++ b/exceptions.cpp
@@ -0,0 +1,8 @@
+#include <string>
+#include "include/exceptions.hpp"
+
+using std::string;
+
+string Exception::showMsg(){
+ return error_msg;
+}
diff --git a/include/exceptions.hpp b/include/exceptions.hpp
index 0469784..4b5fcfa 100644
--- a/include/exceptions.hpp
+++ b/include/exceptions.hpp
@@ -1,4 +1,9 @@
+/* PIA - Lenguajes Modernos de Programación
+ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS
+ * Luis Sebastián Martínez Vega - LCC */
+
#include <string>
+
#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H
@@ -6,18 +11,18 @@ class Exception{
private:
std::string error_msg;
public:
- Exception(const std::string &error_msg);
+ explicit Exception(const std::string &error_msg): error_msg(error_msg){}
std::string showMsg();
};
class LexerException: public Exception{
public:
- LexerException(const std::string &error_msg): Exception(error_msg){}
+ explicit LexerException(const std::string &error_msg): Exception(error_msg){}
};
class ParserException: public Exception{
public:
- ParserException(const std::string &error_msg): Exception(error_msg){}
+ explicit ParserException(const std::string &error_msg): Exception(error_msg){}
};
#endif /* EXCEPTIONS_H */
diff --git a/include/lexer.hpp b/include/lexer.hpp
index e674999..27779ea 100644
--- a/include/lexer.hpp
+++ b/include/lexer.hpp
@@ -33,7 +33,7 @@ enum token_type{
struct Token{
token_type type;
std::string value;
- Token(token_type type, std::string value) : type(type), value(value){}
+ Token(token_type type, const std::string &value) : type(type), value(value){}
};
class Lexer{
@@ -42,7 +42,7 @@ private:
std::string text;
size_t current_char;
Token current_token;
- bool matchFunction(std::string function_name);
+ bool matchFunction(const std::string &function_name);
std::string createNumber();
public:
Lexer(std::string text = {});
diff --git a/lexer.cpp b/lexer.cpp
index 9cfb2f7..666b999 100644
--- a/lexer.cpp
+++ b/lexer.cpp
@@ -16,6 +16,7 @@ Lexer::Lexer(string text): current_token(nil, {}){
void Lexer::setText(string text){
this->text = text;
// Inicializamos el lexer.
+ current_char = 0;
current_token = nextToken();
var_name = '\0';
}
@@ -24,8 +25,8 @@ Token Lexer::getCurrentToken(){
return current_token;
}
-bool Lexer::matchFunction(string function_name){
- string name = text.substr(current_char, 2);
+bool Lexer::matchFunction(const string &function_name){
+ string name = text.substr(current_char, 3);
bool matched = name == function_name;
// Si hubo una coincidencia movemos el puntero.
@@ -48,8 +49,12 @@ string Lexer::createNumber(){
}
Token Lexer::match(){
+ // Si ya consumimos todo el texto,
+ // regresamos nil.
+ if(current_char >= text.length())
+ return Token(nil, {});
// Probamos las funciones.
- if(current_char + 2 < text.length())
+ if(isalpha(text[current_char]) && current_char + 2 <= text.length())
{
if(matchFunction("sin"))
return Token(function, "sin");
@@ -71,7 +76,12 @@ Token Lexer::match(){
/* Si es la primera vez que se lee un token variable o
si la variable leída es igual a la anteriormente leída. */
if(var_name == '\0' || var_name == text[current_char])
+ {
+ var_name = text[current_char];
+ ++current_char;
+
return Token(variable, string(1, var_name));
+ }
// Error, se introdujo una expresión con dos o más variables.
throw LexerException("Encontrada más de una variable.");
@@ -103,11 +113,14 @@ Token Lexer::match(){
++current_char;
return Token(right_parens, {});
default:
- throw LexerException("Carácter inválido.");
+ return Token(nil, {});
}
}
Token Lexer::nextToken(){
+ if(text[current_char] == ' ')
+ ++current_char;
+
current_token = match();
return current_token;
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..ee376c2
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,39 @@
+#include <iterator>
+#include <string>
+#include <vector>
+#include <iostream>
+#include "include/lexer.hpp"
+
+using std::string, std::cin, std::cout, std::getline, std::vector,
+ std::begin, std::end;
+
+string types[] = {string(1, '+'), string(1, '-'), string(1, '/'), string(1, '*'),
+ string(1, '^'), "variable", "número", "función", string(1, '('), string(1, ')'), "nil"};
+
+
+void print_tokens(const vector< Token > &tokens){
+ for(auto i = begin(tokens); i != end(tokens); ++i)
+ {
+ if(i->type == variable || i->type == number || i->type == function)
+ cout << "Tipo: " << types[i->type] << "\nValor: " << i->value << '\n';
+ else
+ cout << "Tipo: " << types[i->type] << '\n';
+ }
+}
+
+int main(){
+ vector< Token > tokens;
+ string input;
+ Lexer lexer;
+ getline(cin, input);
+ lexer.setText(input);
+
+ while(lexer.getCurrentToken().type != nil)
+ {
+ tokens.push_back(lexer.getCurrentToken());
+ lexer.nextToken();
+ }
+ print_tokens(tokens);
+
+ return 0;
+}
diff --git a/makefile b/makefile
index 552120b..98d091e 100644
--- a/makefile
+++ b/makefile
@@ -1,7 +1,7 @@
CC=g++
CFLAGS= -std=gnu++17 -g
-DEPS = lexer.hpp
-OBJ = lexer.o main.o
+DEPS = include/lexer.hpp include/exceptions.hpp
+OBJ = lexer.o exceptions.o main.o
%.o : %.cpp $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)