Finish semantic-analysis, fix bugs and add mallocTable

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
Co-authored-by: Juan Barmasch <jbarmasch@itba.edu.ar>
This commit is contained in:
Santiago Lo Coco 2022-06-19 11:32:00 -03:00
parent 61e08f994c
commit d18e3f4a81
27 changed files with 2667 additions and 926 deletions

2
.gitignore vendored
View File

@ -19,3 +19,5 @@ test.*
bison-parser.c
bison-parser.h
flex-scanner.c
bottler.m

View File

@ -5,24 +5,33 @@ project(BFBCompiler C)
add_custom_command(
OUTPUT ../src/frontend/syntactic-analysis/bison-parser.c ../src/frontend/syntactic-analysis/bison-parser.h
# COMMAND bison -d ../src/frontend/syntactic-analysis/bison-grammar.y -o ../src/frontend/syntactic-analysis/bison-parser.c)
COMMAND bison -Wcounterexamples -d ../src/frontend/syntactic-analysis/bison-grammar.y -o ../src/frontend/syntactic-analysis/bison-parser.c)
# COMMAND bison -t -d ../src/frontend/syntactic-analysis/bison-grammar.y -o ../src/frontend/syntactic-analysis/bison-parser.c)
# COMMAND bison -Wcounterexamples -d ../src/frontend/syntactic-analysis/bison-grammar.y -o ../src/frontend/syntactic-analysis/bison-parser.c)
COMMAND bison -t -d ../src/frontend/syntactic-analysis/bison-grammar.y -o ../src/frontend/syntactic-analysis/bison-parser.c)
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
message(NOTICE "El compilador de C es GCC.")
# message(NOTICE "El compilador de C es GCC.")
add_compile_options(-static-libgcc)
add_compile_options(-std=gnu99)
add_compile_options(-O3)
add_compile_options(-Wall)
add_compile_options(-Wextra)
add_compile_options(-g)
add_compile_options(-Wno-implicit-fallthrough)
add_compile_options(-pedantic)
add_compile_options(-pedantic-errors)
add_compile_options(-fsanitize=address)
add_compile_options(-fno-omit-frame-pointer)
add_link_options(-fsanitize=address)
add_custom_command(
OUTPUT ../src/frontend/lexical-analysis/flex-scanner.c
COMMAND flex -o ../src/frontend/lexical-analysis/flex-scanner.c ../src/frontend/lexical-analysis/flex-patterns.l
DEPENDS ../src/frontend/syntactic-analysis/bison-parser.c ../src/frontend/syntactic-analysis/bison-parser.h)
# COMMAND flex --debug -o ../src/frontend/lexical-analysis/flex-scanner.c ../src/frontend/lexical-analysis/flex-patterns.l
DEPENDS ../src/frontend/syntactic-analysis/bison-parser.c ../src/frontend/syntactic-analysis/bison-parser.h)
elseif (CMAKE_C_COMPILER_ID STREQUAL "MSVC")
message(NOTICE "El compilador de C es Microsoft Visual Studio.")
# message(NOTICE "El compilador de C es Microsoft Visual Studio.")
add_custom_command(
OUTPUT ../src/frontend/lexical-analysis/flex-scanner.c
@ -37,22 +46,24 @@ endif ()
add_executable(BFBCompiler
src/main.c
src/backend/semantic-analysis/analyzer.c
src/backend/code-generation/generator.c
src/backend/domain-specific/calculator.c
src/backend/free-tree/free-tree.c
# src/backend/domain-specific/numerical-methods.c
src/backend/support/logger.c
src/frontend/lexical-analysis/flex-actions.c
src/frontend/lexical-analysis/flex-scanner.c
src/frontend/syntactic-analysis/bison-actions.c
src/frontend/syntactic-analysis/bison-parser.c)
include(CheckFunctionExists)
check_function_exists(pow POW_FUNCTION_EXISTS)
# check_symbol_exists(pow "math.h" POW_FUNCTION_EXISTS)
if (NOT POW_FUNCTION_EXISTS)
target_link_libraries(BFBCompiler m)
else ()
target_link_libraries(BFBCompiler)
endif ()
# include(CheckFunctionExists)
# check_function_exists(pow POW_FUNCTION_EXISTS)
# # check_symbol_exists(pow "math.h" POW_FUNCTION_EXISTS)
# if (NOT POW_FUNCTION_EXISTS)
# target_link_libraries(BFBCompiler m)
# else ()
# target_link_libraries(BFBCompiler)
# endif ()
file(GLOB_RECURSE correct_use_cases "doc/examples/correct/use-case-*.b" )
file(GLOB_RECURSE incorrect_use_cases "doc/examples/incorrect/use-case-*.b" )

View File

@ -5,8 +5,8 @@ function g = { x - 2: x < 3,
};
fun h = x/(x-2);
evaluate f in (3);
g(5);
evaluate g in (4);
g(2);
h(2);
print(evaluate h in (3));
print(g(5));
print(evaluate g in (4));
print(g(2));
print(h(2));

View File

@ -3,4 +3,6 @@ function g = { x - 2: x < 3,
x: x > 7
};
print(evaluate g in [3, 5, 7]);
print(evaluate g in (3));
print(evaluate g in (5));
print(evaluate g in (7));

View File

@ -1,6 +1,6 @@
fun f = e^x;
f'(2);
f''(2);
f'''(2);
f''''(2);
f'''''(2);
fun f = 2^x;
print(derivative f in (2));
print(derivative 2 f in (2));
print(derivative 3 f in (2));
print(derivative 4 f in (2));
print(derivative 5 f in (2));

View File

@ -4,4 +4,4 @@ fun f = { x: x < 3,
fun g = { x^2: 6 < x < 7,
x^7: x > 8
};
fun h = fog;
fun h = f o g;

View File

@ -2,4 +2,4 @@ fun f = - x^2 / 2 + 5*x;
fun g = x^2 - 5*x - 2;
fun h = x^2 - 5*x - 82;
integrate [f, g, h] between (2 ~ 7);
print(integrate f between (2 ~ 7) err 5);

View File

@ -1,2 +1,6 @@
fun f = 1/x;
fun g = taylor 5 f;
fun g = f(1) + ((derivative f in (1)) * (x-1)) + ((derivative 2 f in (1))/2) * (x-1)^2;
print(f(1));
print(f(2));
print(g(1));
print(g(2));

81
main.c Normal file
View File

@ -0,0 +1,81 @@
#include <math.h>
#include <stdio.h>
long fact(int n) {
if (n == 0) {
return 1;
} else {
return n * fact(n-1);
}
}
double Differentiate(double f(double x), double x, double h, int grade) {
double sum = 0;
for (int i = 0; i <= grade; i++) {
printf("%g %d %g %g\n", h, grade, pow(h, 4), pow(h, grade));
// printf("%d %f %f %f %g\n", i, sum, fact(grade) / (fact(i) * fact(grade - i)), f(x + (double) i * h), pow(h, grade));
sum += pow(-1, grade - i) * (fact(grade) / (fact(i) * fact(grade - i))) * f(x + (double) i * h) / pow(h, grade);
}
return sum;
}
double f(double x) {
return x*x*x*x*x - x/(2-x*x);
}
double SimpsonsRule(double f(double x), double a, double b, int errGrade) {
int res = 0;
double der4;
double c, cmax;
for (c = a; c <= b; c += 0.1) {
der4 = Differentiate(f, c, sqrt(__DBL_EPSILON__), 4);
if (res < der4) {
res = der4;
cmax = c;
}
}
printf("%f\n", cmax);
double limit = pow(10, -errGrade), n = 1;
double h = fabs(b-a) / n;
double err = (b-a) * pow(h, 4) * res / 180;
while (err > limit) {
printf("%g %g\n", err, limit);
n++;
h = fabs(b-a) / n;
err = (b-a) * pow(h, 4) * res / (double) 180;
}
printf("%d", n);
// function s=simpson(f,a,b,n)
// h=(b-a)/n;
// y=[];for x=a:h:b;y=[y f(x)];end
// E=y(1)+y(end);
// P=sum(y(3:2:end-2)); Im=sum(y(2:2:end-1));
// s=(h/3)*(E+2*P+4*Im);
// end
double x, sum = 0;
int i = 0; // de 2 a n-1
while (i < n) {
x = a + i * h;
if (i % 2 == 0) {
sum += 2 * f(x);
} else {
sum += 4 * f(x);
}
i++;
}
return (h/3) * (f(a) + f(b) + sum);
}
double g(double x) {
return 1/(x*x*x) + x*x;
}
int main(void) {
// printf("%f", )
// printf("der %f\n", Differentiate(g, 1, pow(10, -1), 4));
// printf("der %f\n", );
// printf("culo %g", SimpsonsRule(g, 1, 8, 5));
}

View File

@ -1,10 +1,442 @@
#include "../support/logger.h"
#include "generator.h"
/**
* Implementación de "generator.h".
*/
#include <string.h>
void Generator(int result) {
LogInfo("El resultado de la expresion computada es: '%d'.", result);
#define DEFAULT_ERROR 5
#define Print(...) fprintf(file, ##__VA_ARGS__)
static FILE * file;
void PrintDerivative(Derivative * derivative) {
if (!(derivative->value->type == ID_EXPRESSION && !strcmp(derivative->value->id , "x"))) {
Print("function_handle");
}
Print("(diff(%s, ", derivative->function);
Print("x, %d)", *derivative->grade);
Print(")");
if (!(derivative->value->type == ID_EXPRESSION && !strcmp(derivative->value->id , "x"))) {
Print("(");
PrintExpression(derivative->value);
Print(")");
}
}
void PrintIntegrate(Integrate * integrate) {
Print("quadv(%s, ", integrate->function);
PrintExpression(integrate->lvalue);
Print(", ");
PrintExpression(integrate->rvalue);
Print(", %f)", integrate->error == NULL ? DEFAULT_ERROR : *integrate->error);
}
void PrintEvaluate(Evaluate * evaluate) {
Print("%s", evaluate->function);
Print("(");
PrintExpression(evaluate->value);
Print(")");
}
void PrintExpression(Expression * expression) {
switch (expression->type) {
case DERIVATIVE_EXPRESSION:
PrintDerivative(expression->derivative);
break;
case INTEGRATE_EXPRESSION:
PrintIntegrate(expression->integrate);
break;
case EVALUATE_EXPRESSION:
PrintEvaluate(expression->evaluate);
break;
case NEGATIVE_EXPRESSION:
Print(" - ");
PrintExpression(expression->leftExpression);
break;
case PARENTHESIS_EXPRESSION:
Print("(");
PrintExpression(expression->leftExpression);
Print(")");
break;
case NUMBER_EXPRESSION:
Print("%f", expression->value);
break;
case ADD_EXPRESSION:
PrintExpression(expression->leftExpression);
Print(" + ");
PrintExpression(expression->rightExpression);
break;
case SUB_EXPRESSION:
PrintExpression(expression->leftExpression);
Print(" - ");
PrintExpression(expression->rightExpression);
break;
case MUL_EXPRESSION:
PrintExpression(expression->leftExpression);
Print(" * ");
PrintExpression(expression->rightExpression);
break;
case DIV_EXPRESSION:
PrintExpression(expression->leftExpression);
Print(" / ");
PrintExpression(expression->rightExpression);
break;
case POW_EXPRESSION:
PrintExpression(expression->leftExpression);
Print(".^");
PrintExpression(expression->rightExpression);
break;
case ID_EXPRESSION:
Print("%s", expression->id);
break;
default:
abort();
}
}
void PrintDomain(Domain * domain) {
switch (domain->type) {
case GREATER_DOMAIN:
PrintExpression(domain->left);
Print(" > ");
PrintExpression(domain->right);
break;
case GREATER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" >= ");
PrintExpression(domain->right);
break;
case LESSER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" <= ");
PrintExpression(domain->right);
break;
case LESSER_DOMAIN:
PrintExpression(domain->left);
Print(" < ");
PrintExpression(domain->right);
break;
case EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" == ");
PrintExpression(domain->right);
break;
case NOT_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" != ");
PrintExpression(domain->right);
break;
case LESSER_LESSER_DOMAIN:
case LESSER_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_DOMAIN:
LogError("Invalid boolean comparison");
default:
abort();
break;
}
}
void PrintDomainForFunction(Domain * domain) {
switch (domain->type) {
case GREATER_DOMAIN:
PrintExpression(domain->left);
Print(" > ");
PrintExpression(domain->right);
break;
case GREATER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" >= ");
PrintExpression(domain->right);
break;
case LESSER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" <= ");
PrintExpression(domain->right);
break;
case LESSER_DOMAIN:
PrintExpression(domain->left);
Print(" < ");
PrintExpression(domain->right);
break;
case EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" == ");
PrintExpression(domain->right);
break;
case NOT_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" != ");
PrintExpression(domain->right);
break;
case LESSER_LESSER_DOMAIN:
PrintExpression(domain->left);
Print(" < ");
PrintExpression(domain->mid);
Print(" && ");
PrintExpression(domain->mid);
Print(" < ");
PrintExpression(domain->right);
break;
case LESSER_LESSER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" < ");
PrintExpression(domain->mid);
Print(" && ");
PrintExpression(domain->mid);
Print(" <= ");
PrintExpression(domain->right);
break;
case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
PrintExpression(domain->left);
Print(" <= ");
PrintExpression(domain->mid);
Print(" && ");
PrintExpression(domain->mid);
Print(" <= ");
PrintExpression(domain->right);
break;
case LESSER_EQUAL_LESSER_DOMAIN:
PrintExpression(domain->left);
Print(" <= ");
PrintExpression(domain->mid);
Print(" && ");
PrintExpression(domain->mid);
Print(" < ");
PrintExpression(domain->right);
break;
}
}
void PrintBoolean(Boolean * boolean) {
switch (boolean->type) {
case DOMAIN_BOOLEAN:
PrintDomain(boolean->domain);
break;
case OR_BOOLEAN:
PrintBoolean(boolean->left);
Print(" || ");
PrintBoolean(boolean->right);
break;
case AND_BOOLEAN:
PrintBoolean(boolean->left);
Print(" && ");
PrintBoolean(boolean->right);
break;
case NOT_BOOLEAN:
Print("!");
PrintBoolean(boolean->left);
break;
case BOOLEAN:
Print("(");
PrintBoolean(boolean->left);
Print(")");
break;
default:
abort();
}
}
void PrintIf(If * if_st) {
Print(" if (");
PrintBoolean(if_st->boolean);
Print(") ");
PrintBlock(if_st->block);
Print(";");
if (if_st->else_block != NULL) {
Print(" else ");
PrintBlock(if_st->else_block);
}
Print("endif");
}
void PrintFor(For * for_st) {
if (for_st->init_variable != NULL) {
PrintDeclareVariable(for_st->init_variable);
Print(";");
}
Print(" while (true)");
Print("if (!(");
PrintBoolean(for_st->boolean);
Print(")) break; endif; ");
PrintAssignVariable(for_st->action_variable);
Print(";");
PrintBlock(for_st->block);
Print(" endwhile");
}
void PrintBlock(Block * block) {
Statement * statement = block->statement;
while (statement != NULL) {
PrintStatement(statement);
statement = statement->next;
}
}
void PrintDeclareVariable(Variable * variable) {
Print("%s", variable->name);
if (variable->value != NULL) {
Print(" = ");
PrintExpression(variable->value);
}
}
void PrintAssignVariable(AssignVariable * variable) {
switch (variable->type) {
case ADD_ASSIGN_EXPRESSION:
Print("%s += ", variable->id);
PrintExpression(variable->expression);
break;
case SUB_ASSIGN_EXPRESSION:
Print("%s -= ", variable->id);
PrintExpression(variable->expression);
break;
case MUL_ASSIGN_EXPRESSION:
Print("%s *= ", variable->id);
PrintExpression(variable->expression);
break;
case DIV_ASSIGN_EXPRESSION:
Print("%s /= ", variable->id);
PrintExpression(variable->expression);
break;
case INCREMENT_EXPRESSION:
Print("%s += 1", variable->id);
break;
case DECREMENT_EXPRESSION:
Print("%s -= 1", variable->id);
break;
case ASSIGN_EXPRESSION:
Print("%s = ", variable->id);
PrintExpression(variable->expression);
break;
default:
abort();
}
}
void PrintPrint(Print * print_st) {
Print("printf(");
switch (print_st->type) {
case STRING_PRINT:
Print("%s", print_st->string);
break;
case EXPRESSION_PRINT:
Print("\"%%f\\n\",");
PrintExpression(print_st->expression);
break;
default:
abort();
}
Print(")");
}
void PrintWhile(While * while_st) {
Print("while (");
PrintBoolean(while_st->boolean);
Print(") ");
PrintBlock(while_st->block);
Print(" endwhile");
}
void PrintCompositeFunction(Composite * composite, char * flag) {
Print("%s(", composite->outter_func);
char flagAux = 0;
switch (composite->type) {
case ID_COMPOSITE:
Print("%s(x))", composite->inner_func);
break;
case COMPOSITE_COMPOSITE:
PrintCompositeFunction(composite->inner_comp, &flagAux);
if (*flag)
Print(";");
break;
default:
LogError("Invalid composite function");
abort();
break;
}
}
void PrintDomainedFunction(Function * function) {
Print("(");
PrintDomainForFunction(function->domain);
Print(") * ");
PrintExpression(function->expression);
}
void PrintDeclareFunction(Function * function) {
Function * currFunc = function;
Print("%s=function_handle( ", function->name);
char flag = 1;
while (currFunc != NULL) {
switch (currFunc->type) {
case EXPRESSION_FUNCTION:
PrintExpression(currFunc->expression);
break;
case EXPRESSION_DOMAIN_FUNCTION:
PrintDomainedFunction(currFunc);
break;
case COMPOSITE_FUNCTION:
PrintCompositeFunction(currFunc->composite, &flag);
break;
default:
LogError("Incorrect function definition");
abort();
}
currFunc = currFunc->next;
if (currFunc != NULL)
Print(" + ");
}
Print(")");
}
void PrintStatement(Statement * statement) {
switch (statement->type) {
case WHILE_STATEMENT:
PrintWhile(statement->while_st);
break;
case FOR_STATEMENT:
PrintFor(statement->for_st);
break;
case IF_STATEMENT:
PrintIf(statement->if_st);
break;
case PRINT_STATEMENT:
PrintPrint(statement->print);
break;
case INTEGRATE_STATEMENT:
PrintIntegrate(statement->integrate);
break;
case DERIVATIVE_STATEMENT:
PrintDerivative(statement->derivative);
break;
case EVALUATE_STATEMENT:
PrintEvaluate(statement->evaluate);
break;
case DECLARE_VARIABLE_STATEMENT:
PrintDeclareVariable(statement->declareVariable);
break;
case ASSIGN_VARIABLE_STATEMENT:
PrintAssignVariable(statement->assignVariable);
break;
case DECLARE_FUNCTION_STATEMENT:
PrintDeclareFunction(statement->declareFunction);
break;
default:
LogError("Invalid statement");
abort();
}
Print(";\n");
}
void Generator(Program * program, FILE * fileAux) {
file = fileAux;
Statement * currStatement = program->statement;
Print("pkg load symbolic;\n");
Print("sympref quiet on; syms x;\n");
while (currStatement != NULL) {
PrintStatement(currStatement);
currStatement = currStatement->next;
}
}

View File

@ -1,6 +1,19 @@
#ifndef GENERATOR_HEADER
#define GENERATOR_HEADER
void Generator(int result);
#include "../support/nodes.h"
void Generator(Program * program, FILE * file);
void PrintExpression(Expression * expression);
void PrintDomain(Domain * domain);
void PrintBoolean(Boolean * boolean);
void PrintIf(If * if_st);
void PrintDeclareVariable(Variable * variable);
void PrintAssignVariable(AssignVariable * variable);
void PrintPrint(Print * print_st);
void PrintWhile(While * while_st);
void PrintStatement(Statement * statement);
void PrintBlock(Block * block);
#endif

View File

@ -1,25 +0,0 @@
#include "calculator.h"
#include "math.h"
double Add(const double leftAddend, const double rightAddend) {
return leftAddend + rightAddend;
}
double Subtract(const double minuend, const double subtract) {
return minuend - subtract;
}
double Multiply(const double multiplicand, const double multiplier) {
return multiplicand * multiplier;
}
double Divide(const double dividend, const double divisor) {
return dividend / divisor;
}
double Power(const double base, const double exponent) {
if (base == 0 && exponent == 0)
return 0;
return pow(base, exponent);
}

View File

@ -1,14 +0,0 @@
#ifndef CALCULATOR_HEADER
#define CALCULATOR_HEADER
double Add(const double leftAddend, const double rightAddend);
double Subtract(const double minuend, const double subtract);
double Multiply(const double multiplicand, const double multiplier);
double Divide(const double dividend, const double divisor);
double Power(const double base, const double exponent);
#endif

View File

@ -0,0 +1,320 @@
#include "../support/logger.h"
#include "free-tree.h"
MallocTable * table;
void InitializeMallocTable() {
table = malloc(sizeof(MallocTable));
table->elements = malloc(DEFAULT_TABLE_SIZE * sizeof(void *));
table->size = DEFAULT_TABLE_SIZE;
table->used = 0;
}
void AddMalloc(void * pointer) {
if (table->used == table->size) {
table->elements = realloc(table->elements, 2 * table->size);
table->size *= 2;
}
table->elements[table->used++] = pointer;
}
void FreeMallocTable() {
for (int i = 0; i < table->used; i++) {
free(table->elements[i]);
}
free(table->elements);
free(table);
}
// void FreeDerivative(Derivative * derivative) {
// free(derivative->function);
// free(derivative->grade);
// FreeExpression(derivative->value);
// free(derivative);
// }
// void FreeIntegrate(Integrate * integrate) {
// free(integrate->function);
// FreeExpression(integrate->lvalue);
// FreeExpression(integrate->rvalue);
// if (integrate->error != NULL)
// free(integrate->error);
// free(integrate);
// }
// void FreeEvaluate(Evaluate * evaluate) {
// free(evaluate->function);
// FreeExpression(evaluate->value);
// free(evaluate);
// }
// void FreeExpression(Expression * expression) {
// switch (expression->type) {
// case DERIVATIVE_EXPRESSION:
// FreeDerivative(expression->derivative);
// break;
// case INTEGRATE_EXPRESSION:
// FreeIntegrate(expression->integrate);
// break;
// case EVALUATE_EXPRESSION:
// FreeEvaluate(expression->evaluate);
// break;
// case NEGATIVE_EXPRESSION:
// case PARENTHESIS_EXPRESSION:
// FreeExpression(expression->leftExpression);
// break;
// case NUMBER_EXPRESSION:
// break;
// case ADD_EXPRESSION:
// case SUB_EXPRESSION:
// case MUL_EXPRESSION:
// case DIV_EXPRESSION:
// case POW_EXPRESSION:
// FreeExpression(expression->leftExpression);
// FreeExpression(expression->rightExpression);
// break;
// case ID_EXPRESSION:
// free(expression->id);
// break;
// default:
// abort();
// }
// free(expression);
// }
// void FreeDomain(Domain * domain) {
// switch (domain->type) {
// case GREATER_DOMAIN:
// case GREATER_EQUAL_DOMAIN:
// case LESSER_EQUAL_DOMAIN:
// case LESSER_DOMAIN:
// case EQUAL_DOMAIN:
// case NOT_EQUAL_DOMAIN:
// FreeExpression(domain->left);
// FreeExpression(domain->right);
// break;
// case LESSER_LESSER_DOMAIN:
// case LESSER_LESSER_EQUAL_DOMAIN:
// case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
// case LESSER_EQUAL_LESSER_DOMAIN:
// // FreeExpression(domain->left);
// // FreeExpression(domain->mid);
// // FreeExpression(domain->right);
// break;
// default:
// abort();
// break;
// }
// free(domain);
// }
// void FreeDomainForFunction(Domain * domain) {
// switch (domain->type) {
// case GREATER_DOMAIN:
// case GREATER_EQUAL_DOMAIN:
// case LESSER_EQUAL_DOMAIN:
// case LESSER_DOMAIN:
// case EQUAL_DOMAIN:
// case NOT_EQUAL_DOMAIN:
// FreeExpression(domain->left);
// FreeExpression(domain->right);
// break;
// case LESSER_LESSER_DOMAIN:
// case LESSER_LESSER_EQUAL_DOMAIN:
// case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
// case LESSER_EQUAL_LESSER_DOMAIN:
// FreeExpression(domain->left);
// FreeExpression(domain->mid);
// FreeExpression(domain->right);
// break;
// }
// free(domain);
// }
// void FreeBoolean(Boolean * boolean) {
// switch (boolean->type) {
// case DOMAIN_BOOLEAN:
// FreeDomain(boolean->domain);
// break;
// case OR_BOOLEAN:
// case AND_BOOLEAN:
// FreeBoolean(boolean->left);
// FreeBoolean(boolean->right);
// break;
// case NOT_BOOLEAN:
// case BOOLEAN:
// FreeBoolean(boolean->left);
// break;
// default:
// abort();
// }
// free(boolean);
// }
// void FreeIf(If * if_st) {
// FreeBoolean(if_st->boolean);
// FreeBlock(if_st->block);
// if (if_st->else_block != NULL) {
// FreeBlock(if_st->else_block);
// }
// free(if_st);
// }
// void FreeFor(For * for_st) {
// if (for_st->init_variable != NULL)
// FreeDeclareVariable(for_st->init_variable);
// FreeBoolean(for_st->boolean);
// FreeAssignVariable(for_st->action_variable);
// FreeBlock(for_st->block);
// free(for_st);
// }
// void FreeBlock(Block * block) {
// Statement * statement = block->statement, * aux;
// while (statement != NULL) {
// aux = statement;
// statement = statement->next;
// FreeStatement(aux);
// }
// free(block);
// }
// void FreeDeclareVariable(Variable * variable) {
// free(variable->name);
// if (variable->value != NULL) {
// FreeExpression(variable->value);
// }
// free(variable);
// }
// void FreeAssignVariable(AssignVariable * variable) {
// switch (variable->type) {
// case INCREMENT_EXPRESSION:
// case DECREMENT_EXPRESSION:
// break;
// case ADD_ASSIGN_EXPRESSION:
// case SUB_ASSIGN_EXPRESSION:
// case MUL_ASSIGN_EXPRESSION:
// case DIV_ASSIGN_EXPRESSION:
// case ASSIGN_EXPRESSION:
// FreeExpression(variable->expression);
// break;
// default:
// abort();
// }
// free(variable->id);
// free(variable);
// }
// void FreePrint(Print * print_st) {
// switch (print_st->type) {
// case STRING_PRINT:
// free(print_st->string);
// break;
// case EXPRESSION_PRINT:
// FreeExpression(print_st->expression);
// break;
// default:
// abort();
// }
// free(print_st);
// }
// void FreeWhile(While * while_st) {
// FreeBoolean(while_st->boolean);
// FreeBlock(while_st->block);
// free(while_st);
// }
// void FreeCompositeFunction(Composite * composite) {
// switch (composite->type) {
// case ID_COMPOSITE:
// free(composite->inner_func);;
// break;
// case COMPOSITE_COMPOSITE:
// FreeCompositeFunction(composite->inner_comp);
// break;
// default:
// LogError("Invalid composite function");
// abort();
// }
// free(composite->outter_func);
// free(composite);
// }
// void FreeDeclareFunction(Function * function) {
// Function * currFunc = function;
// free(function->name);
// Function * aux;
// while (currFunc != NULL) {
// switch (currFunc->type) {
// case EXPRESSION_FUNCTION:
// FreeExpression(currFunc->expression);
// break;
// case EXPRESSION_DOMAIN_FUNCTION:
// FreeExpression(currFunc->expression);
// FreeDomainForFunction(currFunc->domain);
// break;
// case COMPOSITE_FUNCTION:
// FreeCompositeFunction(currFunc->composite);
// break;
// default:
// LogError("Incorrect function definition");
// abort();
// }
// aux = currFunc;
// currFunc = currFunc->next;
// free(aux);
// }
// }
// void FreeStatement(Statement * statement) {
// switch (statement->type) {
// case WHILE_STATEMENT:
// FreeWhile(statement->while_st);
// break;
// case FOR_STATEMENT:
// FreeFor(statement->for_st);
// break;
// case IF_STATEMENT:
// FreeIf(statement->if_st);
// break;
// case PRINT_STATEMENT:
// FreePrint(statement->print);
// break;
// case INTEGRATE_STATEMENT:
// FreeIntegrate(statement->integrate);
// break;
// case DERIVATIVE_STATEMENT:
// FreeDerivative(statement->derivative);
// break;
// case EVALUATE_STATEMENT:
// FreeEvaluate(statement->evaluate);
// break;
// case DECLARE_VARIABLE_STATEMENT:
// FreeDeclareVariable(statement->declareVariable);
// break;
// case ASSIGN_VARIABLE_STATEMENT:
// FreeAssignVariable(statement->assignVariable);
// break;
// case DECLARE_FUNCTION_STATEMENT:
// FreeDeclareFunction(statement->declareFunction);
// break;
// default:
// LogError("Invalid statement");
// abort();
// }
// free(statement);
// }
// void FreeTree(Program * program) {
// if (program == NULL)
// return;
// Statement * currStatement = program->statement, * aux;
// while (currStatement != NULL) {
// aux = currStatement;
// currStatement = currStatement->next;
// FreeStatement(aux);
// }
// }

View File

@ -0,0 +1,31 @@
#ifndef FREE_TREE_HEADER
#define FREE_TREE_HEADER
#include "../support/nodes.h"
void FreeTree(Program * program);
void FreeExpression(Expression * expression);
void FreeDomain(Domain * domain);
void FreeBoolean(Boolean * boolean);
void FreeIf(If * if_st);
void FreeDeclareVariable(Variable * variable);
void FreeAssignVariable(AssignVariable * variable);
void FreePrint(Print * print_st);
void FreeWhile(While * while_st);
void FreeStatement(Statement * statement);
void FreeBlock(Block * block);
#define DEFAULT_TABLE_SIZE 500
typedef struct MallocTable {
void ** elements;
int used;
int size;
} MallocTable;
void InitializeMallocTable();
void AddMalloc(void * pointer);
void FreeMallocTable();
#endif

View File

@ -1,7 +0,0 @@
# Analizador Semántico
¿Qué se debería implementar en esta parte del proyecto?
El analizador semántico debe ser el encargado de analizar el árbol de sintaxis abstracta construido desde el analizador sintáctico (_i.e._, Bison), aplicando todas las reglas del dominio específico que el lenguaje resuelve, garantizando que el significado (la semántica) del programa, es correcto. Esto implica verificar que las operaciones estén bien formadas, que los parámetros y tipos sean correctos, que la definición de las variables (en caso de existir dicho concepto), sean consistentes, entre muchos otros detalles asociados a la especificación del lenguaje.
Si el analizador semántico logra validar el programa completo, entonces se procede a la última fase: la __generación de código__. Nótese que la generación de código no necesariamente implica emitir un nuevo programa (por ejemplo, un ejecutable, o código en _assembler_ listo para compilar). Para un programa que permita procesar datos, la generación de código puede implicar emitir un set de datos, o un simple resultado, como es el caso de este proyecto base (que computa el resultado de un cálculo aritmético, y lo muestra por consola).

View File

@ -0,0 +1,496 @@
#include "../support/nodes.h"
#include "../support/logger.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define DEFAULT_SIZE 20
typedef struct Table {
char ** elements;
int used;
int size;
struct Table * prev;
} Table;
typedef struct Stack {
Table * top;
} Stack;
bool AnalyzeDerivative(Derivative * derivative, Stack * stack);
bool AnalyzeStatement(Statement * statement, Stack * stack);
bool AnalyzeEvaluate(Evaluate * evaluate, Stack * stack);
bool AnalyzeIntegrate(Integrate * integrate, Stack * stack);
bool AnalyzeFunctionDerivative(Derivative * derivative, Stack * stack);
bool AnalyzeFunctionStatement(Statement * statement, Stack * stack);
bool AnalyzeFunctionEvaluate(Evaluate * evaluate, Stack * stack);
bool AnalyzeFunctionIntegrate(Integrate * integrate, Stack * stack);
bool FindVar(Table * table, char * name) {
for (int i = 0; i < table->used; i++) {
if (!strcmp(name, table->elements[i]))
return true;
}
return false;
}
void CopyTable(Table * src, Table * dest) {
dest->size = src->size;
dest->used = src->used;
for (int i = 0; i < src->used; i++) {
dest->elements[i] = malloc(strlen(src->elements[i]) + 1);
strcpy(dest->elements[i], src->elements[i]);
}
}
Table * PushNewTable(Stack * stack) {
Table * newTable;
newTable = malloc(sizeof(Table));
if (stack->top != NULL) {
newTable->elements = malloc(stack->top->size * sizeof(char *));
CopyTable(stack->top, newTable);
}
else {
newTable->elements = malloc(DEFAULT_SIZE * sizeof(char *));
newTable->size = DEFAULT_SIZE;
newTable->used = 0;
}
newTable->prev = stack->top;
stack->top = newTable;
return newTable;
}
void PopTable(Stack * stack) {
if (stack->top == NULL)
return;
Table * poppedTable = stack->top;
stack->top = poppedTable->prev;
for (int i = 0; i < poppedTable->used; i++) {
free(poppedTable->elements[i]);
}
free(poppedTable->elements);
free(poppedTable);
}
void AddVar(Table * table, char * varName) {
if (table->used == table->size) {
table->elements = realloc(table->elements, table->size * 2);
table->size *= 2;
}
table->elements[table->used] = malloc(strlen(varName) + 1);
strcpy(table->elements[table->used++], varName);
}
bool AnalyzeComposite(Composite * composite, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, composite->outter_func)) {
LogError("Function %s not defined", composite->outter_func);
return false;
}
if (composite->type == COMPOSITE_COMPOSITE)
return AnalyzeComposite(composite->inner_comp, stack);
else {
if (!FindVar(table, composite->inner_func)) {
LogError("Variable %s not defined", composite->inner_func);
return false;
}
}
return true;
}
bool AnalyzeExpression(Expression * expression, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
switch (expression->type) {
case DERIVATIVE_EXPRESSION:
return AnalyzeDerivative(expression->derivative, stack);
case INTEGRATE_EXPRESSION:
return AnalyzeIntegrate(expression->integrate, stack);
case EVALUATE_EXPRESSION:
return AnalyzeEvaluate(expression->evaluate, stack);
case NEGATIVE_EXPRESSION:
case PARENTHESIS_EXPRESSION:
return AnalyzeExpression(expression->leftExpression, stack);
case NUMBER_EXPRESSION:
break;
case ADD_EXPRESSION:
case SUB_EXPRESSION:
case MUL_EXPRESSION:
case DIV_EXPRESSION:
case POW_EXPRESSION:
if (!AnalyzeExpression(expression->leftExpression, stack))
return false;
return AnalyzeExpression(expression->rightExpression, stack);
case ID_EXPRESSION:
if (!FindVar(table, expression->id)) {
LogError("Variable %s not defined", expression->id);
return false;
}
break;
default:
return false;
}
return true;
}
bool AnalyzeFunctionExpression(Expression * expression, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
switch (expression->type) {
case DERIVATIVE_EXPRESSION:
return AnalyzeFunctionDerivative(expression->derivative, stack);
case INTEGRATE_EXPRESSION:
return AnalyzeFunctionIntegrate(expression->integrate, stack);
case EVALUATE_EXPRESSION:
return AnalyzeFunctionEvaluate(expression->evaluate, stack);
case NEGATIVE_EXPRESSION:
case PARENTHESIS_EXPRESSION:
return AnalyzeFunctionExpression(expression->leftExpression, stack);
case NUMBER_EXPRESSION:
break;
case ADD_EXPRESSION:
case SUB_EXPRESSION:
case MUL_EXPRESSION:
case DIV_EXPRESSION:
case POW_EXPRESSION:
if (!AnalyzeFunctionExpression(expression->leftExpression, stack))
return false;
return AnalyzeFunctionExpression(expression->rightExpression, stack);
case ID_EXPRESSION:
if (strcmp(expression->id, "x")) {
LogError("Function expression must only have \'x\' as a variable");
return false;
}
break;
default:
LogError("Invalid expression");
return false;
}
return true;
}
bool AnalyzeFunctionDomain(Domain * domain, Stack * stack) {
switch (domain->type) {
case GREATER_DOMAIN:
case GREATER_EQUAL_DOMAIN:
case LESSER_EQUAL_DOMAIN:
case LESSER_DOMAIN:
case EQUAL_DOMAIN:
case NOT_EQUAL_DOMAIN:
if (!AnalyzeFunctionExpression(domain->left, stack))
return false;
return AnalyzeFunctionExpression(domain->right, stack);
case LESSER_LESSER_DOMAIN:
case LESSER_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_DOMAIN:
if (!AnalyzeFunctionExpression(domain->left, stack))
return false;
if (!AnalyzeFunctionExpression(domain->mid, stack))
return false;
return AnalyzeFunctionExpression(domain->right, stack);
default:
LogError("Invalid domain");
return false;
}
return true;
}
bool AnalyzeDomain(Domain * domain, Stack * stack) {
switch (domain->type) {
case GREATER_DOMAIN:
case GREATER_EQUAL_DOMAIN:
case LESSER_EQUAL_DOMAIN:
case LESSER_DOMAIN:
case EQUAL_DOMAIN:
case NOT_EQUAL_DOMAIN:
if (!AnalyzeExpression(domain->left, stack))
return false;
return AnalyzeExpression(domain->right, stack);
case LESSER_LESSER_DOMAIN:
case LESSER_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_EQUAL_DOMAIN:
case LESSER_EQUAL_LESSER_DOMAIN:
break;
default:
LogError("Invalid domain");
return false;
}
return true;
}
bool AnalyzeBoolean(Boolean * boolean, Stack * stack) {
switch (boolean->type) {
case DOMAIN_BOOLEAN:
case NOT_BOOLEAN:
case BOOLEAN:
if (!AnalyzeDomain(boolean->domain, stack))
return false;
break;
case OR_BOOLEAN:
case AND_BOOLEAN:
if (!AnalyzeBoolean(boolean->left, stack))
return false;
return AnalyzeBoolean(boolean->right, stack);
default:
LogError("Invalid boolean");
return false;
}
return true;
}
bool AnalyzeDeclareVariable(Variable * variable, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!strcmp(variable->name, "x")) {
LogError("Cannot use variable name 'x' outside of function");
return false;
}
if (!FindVar(table, variable->name)) {
AddVar(table, variable->name);
}
return true;
}
bool AnalyzeDeclareFunction(Function * function, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (function->name != NULL) {
if (!strcmp(function->name, "x")) {
LogError("Cannot use function name 'x'");
return false;
}
if (!FindVar(table, function->name)) {
AddVar(table, function->name);
}
}
switch (function->type) {
case EXPRESSION_FUNCTION:
if (!AnalyzeFunctionExpression(function->expression, stack))
return false;
break;
case EXPRESSION_DOMAIN_FUNCTION:
if (!AnalyzeFunctionDomain(function->domain, stack))
return false;
if (!AnalyzeFunctionExpression(function->expression, stack))
return false;
break;
case COMPOSITE_FUNCTION:
if (!AnalyzeComposite(function->composite, stack))
return false;
break;
default:
LogError("Invalid function");
return false;
}
if (function->next != NULL)
return AnalyzeDeclareFunction(function->next, stack);
return true;
}
bool AnalyzeAssignVariable(AssignVariable * assign, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, assign->id)) {
LogError("Variable %s not defined", assign->id);
return false;
}
return true;
}
bool AnalyzeBlock(Block * block, Stack * stack) {
PushNewTable(stack);
Statement * currStatement = block->statement;
while (currStatement != NULL) {
if (!AnalyzeStatement(currStatement, stack))
return false;
currStatement = currStatement->next;
}
PopTable(stack);
return true;
}
bool AnalyzeWhile(While * while_st, Stack * stack) {
return AnalyzeBlock(while_st->block, stack);
}
bool AnalyzeIf(If * if_st, Stack * stack) {
AnalyzeBlock(if_st->block, stack);
if (if_st->else_block != NULL)
return AnalyzeBlock(if_st->else_block, stack);
return true;
}
bool AnalyzeFor(For * for_st, Stack * stack) {
if (for_st->init_variable != NULL) {
if (!AnalyzeDeclareVariable(for_st->init_variable, stack))
return false;
}
if (!AnalyzeAssignVariable(for_st->action_variable, stack))
return false;
return AnalyzeBlock(for_st->block, stack);
}
bool AnalyzePrint(Print * print, Stack * stack) {
if (print->type == EXPRESSION_PRINT)
return AnalyzeExpression(print->expression, stack);
return true;
}
bool AnalyzeIntegrate(Integrate * integrate, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, integrate->function)) {
LogError("Function %s not defined", integrate->function);
return false;
}
if (!AnalyzeExpression(integrate->lvalue, stack))
return false;
return AnalyzeExpression(integrate->rvalue, stack);
}
bool AnalyzeFunctionIntegrate(Integrate * integrate, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, integrate->function)) {
LogError("Function %s not defined", integrate->function);
return false;
}
if (!AnalyzeFunctionExpression(integrate->lvalue, stack))
return false;
return AnalyzeFunctionExpression(integrate->rvalue, stack);
}
bool AnalyzeDerivative(Derivative * derivative, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, derivative->function)) {
LogError("Function %s not defined", derivative->function);
return false;
}
return AnalyzeExpression(derivative->value, stack);
}
bool AnalyzeFunctionDerivative(Derivative * derivative, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, derivative->function)) {
LogError("Function %s not defined", derivative->function);
return false;
}
return AnalyzeFunctionExpression(derivative->value, stack);
}
bool AnalyzeEvaluate(Evaluate * evaluate, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, evaluate->function)) {
LogError("Function %s not defined", evaluate->function);
return false;
}
return AnalyzeExpression(evaluate->value, stack);
}
bool AnalyzeFunctionEvaluate(Evaluate * evaluate, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
if (!FindVar(table, evaluate->function)) {
LogError("Function %s not defined", evaluate->function);
return false;
}
return AnalyzeFunctionExpression(evaluate->value, stack);
}
bool AnalyzeStatement(Statement * statement, Stack * stack) {
Table * table = stack->top;
if (table == NULL) {
LogError("Semantic analyzer error");
return false;
}
switch (statement->type) {
case WHILE_STATEMENT:
return AnalyzeWhile(statement->while_st, stack);
case FOR_STATEMENT:
return AnalyzeFor(statement->for_st, stack);
case IF_STATEMENT:
return AnalyzeIf(statement->if_st, stack);
case PRINT_STATEMENT:
return AnalyzePrint(statement->print, stack);
case INTEGRATE_STATEMENT:
return AnalyzeIntegrate(statement->integrate, stack);
case DERIVATIVE_STATEMENT:
return AnalyzeDerivative(statement->derivative, stack);
case EVALUATE_STATEMENT:
return AnalyzeEvaluate(statement->evaluate, stack);
case DECLARE_VARIABLE_STATEMENT:
return AnalyzeDeclareVariable(statement->declareVariable, stack);
case ASSIGN_VARIABLE_STATEMENT:
return AnalyzeAssignVariable(statement->assignVariable, stack);
case DECLARE_FUNCTION_STATEMENT:
return AnalyzeDeclareFunction(statement->declareFunction, stack);
default:
LogError("Invalid statement");
return false;
}
return true;
}
bool Analyze(Program * program) {
Statement * currStatement = program->statement;
Stack * stack = calloc(1, sizeof(Stack));
bool success = true;
PushNewTable(stack);
while (currStatement != NULL) {
if (!AnalyzeStatement(currStatement, stack)) {
success = false;
break;
}
currStatement = currStatement->next;
}
while (stack->top != NULL)
PopTable(stack);
free(stack);
return success;
}

View File

@ -0,0 +1,9 @@
#ifndef ANALYZER_HEADER
#define ANALYZER_HEADER
#include "../support/nodes.h"
#include <stdbool.h>
bool Analyze(Program * program);
#endif

View File

@ -4,162 +4,220 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct variable_t {
char * name;
struct expression_t * value;
} variable_t;
typedef struct Program {
struct Statement * statement;
} Program;
typedef struct while_t {
struct boolean_t * boolean;
struct block_t * block;
} while_t;
typedef enum {
WHILE_STATEMENT,
PRINT_STATEMENT,
FOR_STATEMENT,
IF_STATEMENT,
INTEGRATE_STATEMENT,
DERIVATIVE_STATEMENT,
EVALUATE_STATEMENT,
ASSIGN_VARIABLE_STATEMENT,
DECLARE_VARIABLE_STATEMENT,
DECLARE_FUNCTION_STATEMENT
} StatementType;
typedef struct expression_t {
struct algebraic_op_t * algebraic_op;
double * number;
struct variable_t * variable;
struct derivative_t * derivative;
struct integrate_t * integrate;
struct evaluate_t * evaluate;
struct negative_t * negative;
struct parenthesis_exp_t * parenthesis_exp;
typedef struct Statement {
StatementType type;
struct expression_t * next;
} expression_t;
typedef struct function_t {
char * name;
expression_t * expression;
struct domain_t * domain;
struct taylor_t * taylor;
struct composite_t * composite;
struct function_t * next;
} function_t;
typedef struct statement_t {
struct while_t * while_st;
struct print_t * print;
struct for_t * for_st;
struct if_t * if_st;
struct integrate_t * integrate;
struct derivative_t * derivative;
struct evaluate_t * evaluate;
struct variable_t * variable;
struct While * while_st;
struct Print * print;
struct For * for_st;
struct If * if_st;
struct Integrate * integrate;
struct Derivative * derivative;
struct Evaluate * evaluate;
struct AssignVariable * assignVariable;
struct Variable * declareVariable;
struct Function * declareFunction;
struct statement_t * next;
} statement_t;
struct Statement * next;
} Statement;
typedef struct block_t {
statement_t * statement;
} block_t;
typedef struct Variable {
char * name;
struct Expression * value;
} Variable;
typedef struct print_t {
expression_t * exp;
typedef struct While {
struct Boolean * boolean;
struct Block * block;
} While;
typedef enum {
DERIVATIVE_EXPRESSION,
INTEGRATE_EXPRESSION,
EVALUATE_EXPRESSION,
NEGATIVE_EXPRESSION,
PARENTHESIS_EXPRESSION,
NUMBER_EXPRESSION,
ADD_EXPRESSION,
SUB_EXPRESSION,
MUL_EXPRESSION,
DIV_EXPRESSION,
POW_EXPRESSION,
ID_EXPRESSION
} ExpressionType;
typedef struct Expression {
ExpressionType type;
struct Expression * leftExpression;
struct Expression * rightExpression;
// struct Variable * variable;
struct Derivative * derivative;
struct Integrate * integrate;
struct Evaluate * evaluate;
struct NegativeExp * negative;
struct ParenthesisExp * parenthesis;
double value;
char * id;
struct Expression * next;
} Expression;
typedef enum {
EXPRESSION_FUNCTION,
EXPRESSION_DOMAIN_FUNCTION,
COMPOSITE_FUNCTION,
} FunctionType;
typedef struct Function {
FunctionType type;
char * name;
struct Expression * expression;
struct Domain * domain;
struct Composite * composite;
struct Function * next;
} Function;
typedef struct Block {
Statement * statement;
} Block;
typedef enum {
EXPRESSION_PRINT,
STRING_PRINT
} PrintType;
typedef struct Print {
PrintType type;
Expression * expression;
char * string;
} print_t;
} Print;
typedef struct for_t {
variable_t * variable_t;
struct boolean_t * boolean;
block_t * block;
} for_t;
typedef struct For {
Variable * init_variable;
struct AssignVariable * action_variable;
struct Boolean * boolean;
Block * block;
} For;
typedef struct if_t {
struct boolean_t * boolean;
block_t * block;
block_t * else_block;
} if_t;
typedef struct If {
struct Boolean * boolean;
Block * block;
Block * else_block;
} If;
typedef struct boolean_t {
struct domain_t * domain;
struct not_bool_t * not_bool;
struct bool_op_t * bool_op;
} boolean_t;
typedef enum {
DOMAIN_BOOLEAN,
OR_BOOLEAN,
AND_BOOLEAN,
BOOLEAN,
NOT_BOOLEAN
} BooleanType;
typedef struct bool_op_t {
boolean_t * left;
boolean_t * right;
int op;
} bool_op_t;
typedef struct Boolean {
BooleanType type;
typedef struct not_bool_t {
boolean_t * boolean;
} not_bool_t;
struct Domain * domain;
struct Boolean * left;
struct Boolean * right;
} Boolean;
typedef struct domain_one_op_t {
expression_t * left;
expression_t * right;
int oper;
} domain_one_op_t;
typedef enum {
GREATER_DOMAIN,
GREATER_EQUAL_DOMAIN,
LESSER_EQUAL_DOMAIN,
LESSER_DOMAIN,
EQUAL_DOMAIN,
NOT_EQUAL_DOMAIN,
LESSER_LESSER_DOMAIN,
LESSER_LESSER_EQUAL_DOMAIN,
LESSER_EQUAL_LESSER_EQUAL_DOMAIN,
LESSER_EQUAL_LESSER_DOMAIN
} DomainType;
typedef struct domain_two_op_t {
expression_t * left;
expression_t * mid;
expression_t * right;
int oper1;
int oper2;
} domain_two_op_t;
typedef struct Domain {
DomainType type;
typedef struct domain_t {
domain_one_op_t * domain_one;
domain_two_op_t * domain_two;
} domain_t;
Expression * left;
Expression * mid;
Expression * right;
} Domain;
typedef struct parenthesis_exp_t {
expression_t * expression;
} parenthesis_exp_t;
typedef struct negative_t {
expression_t * expression;
} negative_t;
typedef struct derivative_t {
function_t * function;
double * value;
typedef struct Derivative {
char * function;
Expression * value;
int * grade;
double * error;
} derivative_t;
} Derivative;
typedef struct evaluate_t {
function_t * function;
double * value;
} evaluate_t;
typedef struct Evaluate {
char * function;
Expression * value;
} Evaluate;
typedef struct integrate_t {
function_t * function;
double * value;
typedef struct Integrate {
char * function;
double * error;
expression_t * lvalue;
expression_t * rvalue;
} integrate_t;
Expression * lvalue;
Expression * rvalue;
} Integrate;
typedef struct algebraic_op_t {
expression_t * left;
expression_t * right;
int op;
} algebraic_op_t;
typedef enum {
ID_COMPOSITE,
COMPOSITE_COMPOSITE
} CompositeType;
typedef struct composite_t {
function_t * outter_funct;
function_t * inner_funct;
} composite_t;
typedef struct Composite {
CompositeType type;
char * outter_func;
typedef struct numArray_t {
expression_t * expressions;
size_t size;
struct Composite * inner_comp;
char * inner_func;
} Composite;
struct numArray_t * next;
} numArray_t;
// typedef struct NumArray {
// Expression * expressions;
// size_t size;
typedef struct taylor_t {
int num;
function_t * function;
} taylor_t;
// struct NumArray * next;
// } NumArray;
typedef struct id_t {
variable_t * variable;
function_t * function;
} id_t;
typedef enum {
ADD_ASSIGN_EXPRESSION,
SUB_ASSIGN_EXPRESSION,
MUL_ASSIGN_EXPRESSION,
DIV_ASSIGN_EXPRESSION,
INCREMENT_EXPRESSION,
DECREMENT_EXPRESSION,
ASSIGN_EXPRESSION
} AssignVariableType;
typedef struct AssignVariable {
AssignVariableType type;
char * id;
Expression * expression;
} AssignVariable;
#endif

View File

@ -2,54 +2,33 @@
#define SHARED_HEADER
#include <stdio.h>
#include "nodes.h"
#include <stdbool.h>
// Descriptor del archivo de entrada que utiliza Bison.
extern FILE * yyin;
// Descriptor del archivo de salida que utiliza Bison.
extern FILE * yyout;
// Variable global que contiene el número escaneado.
extern int yylval;
// Variable global que contiene el número de la línea analizada.
extern int yylineno;
// Token actual en el tope de la pila del analizador Bison.
extern char * yytext;
// Función global de manejo de errores en Bison.
extern void yyerror(const char * string);
// Función global del analizador léxico Flex.
extern int yylex(void);
// Función global del analizador sintáctico Bison.
extern int yyparse(void);
// Emular tipo "boolean".
typedef enum {
false = 0,
true = 1
} boolean;
// typedef enum {
// false = 0,
// true = 1
// } boolean;
// Estado global de toda la aplicación.
typedef struct {
// Indica si la compilación tuvo problemas hasta el momento:
boolean succeed;
// Indica el resultado de la compilación:
int result;
bool succeed;
// Agregar una pila para almacenar tokens/nodos.
// Agregar un nodo hacia la raíz del árbol de sintaxis abstracta.
// Agregar una tabla de símbolos.
// ...
Program * program;
} CompilerState;
// El estado se define e inicializa en el archivo "main.c":
extern CompilerState state;
#endif

View File

@ -1,38 +1,38 @@
#include "../../backend/support/logger.h"
#include "../../backend/free-tree/free-tree.h"
#include "flex-actions.h"
#include <stdlib.h>
#include <string.h>
/**
* Implementación de "flex-rules.h".
*/
TokenID IntegerPatternAction(const char * lexeme) {
// LogDebug("IntegerPatternAction: '%s'.", lexeme);
yylval = atoi(lexeme);
int IntegerPatternAction(const char * lexeme) {
yylval.intNumber = atoi(lexeme);
return INTEGER;
}
TokenID DoublePatternAction(const char * lexeme) {
// LogDebug("DoublePatternAction: '%s'.", lexeme);
yylval = atof(lexeme);
int DoublePatternAction(const char * lexeme) {
yylval.doubleNumber = atof(lexeme);
return DOUBLE;
}
TokenID StringPatternAction(const char * lexeme) {
// LogDebug("StringPatternAction: '%s'.", lexeme);
int StringPatternAction(char * lexeme) {
char * aux = malloc(strlen(lexeme) + 1);
AddMalloc(aux);
strcpy(aux, lexeme);
yylval.string = aux;
return ID;
}
TokenID EscapeStringPatternAction(const char * lexeme) {
// LogDebug("EscapeStringPatternAction: '%s'.", lexeme);
int EscapeStringPatternAction(char * lexeme) {
char * aux = malloc(strlen(lexeme) + 1);
AddMalloc(aux);
strcpy(aux, lexeme);
yylval.string = aux;
return ESCAPESTRING;
}
void IgnoredPatternAction(const char * lexeme) {
// LogDebug("IgnoredPatternAction: '%s'.", lexeme);
}
void IgnoredPatternAction() {}
TokenID UnknownPatternAction(const char * lexeme) {
int UnknownPatternAction(const char * lexeme) {
LogDebug("UnknownPatternAction: '%s'.", lexeme);
return YYUNDEF;
}

View File

@ -2,93 +2,69 @@
#define FLEX_ACTIONS_HEADER
#include "../../backend/support/shared.h"
#include "../syntactic-analysis/bison-parser.h"
/**
* Se definen los diferentes IDs de cada token disponible para el scanner Flex.
*/
typedef enum TokenID {
// typedef enum TokenID {
// UNKNOWN = 0,
// YYUNDEF = 257,
// ADD,
// SUB,
// MUL,
// DIV,
// POW,
// FUNCTION,
// IF,
// ELSE,
// FOR,
// WHILE,
// PRINT,
// SEMICOLON,
// COMPOSITE,
// SQUOTE,
// DERIVATIVE,
// INTEGRATE,
// BETWEEN,
// AND_INT,
// EVALUATE,
// IN,
// OPEN_BRACES,
// OPEN_BRACKETS,
// CLOSE_BRACES,
// CLOSE_BRACKETS,
// OPEN_PARENTHESIS,
// CLOSE_PARENTHESIS,
// ASSIGN,
// EQUAL,
// AND,
// OR,
// NOT,
// ADD_ASSIGN,
// INCREMENT,
// SUB_ASSIGN,
// DECREMENT,
// MUL_ASSIGN,
// DIV_ASSIGN,
// DQUOTE,
// COMMA,
// COLON,
// LESSER,
// LESSER_EQUAL,
// GREATER,
// GREATER_EQUAL,
// NOT_EQUAL,
// VAR,
// ERR,
// ESCAPESTRING,
// DOUBLE,
// INTEGER,
// ID
// } TokenID;
// Por defecto, el valor "0" hace fallar el analizador sintáctico.
UNKNOWN = 0,
// Código de error de Bison, que permite abortar el escaneo de lexemas cuando
// se presente un patrón desconocido. El número "257" coincide con el valor
// que Bison le otorga por defecto, pero además permite que el resto de
// tokens continúen desde el valor "258" lo que permite proteger los IDs
// internos que Bison reserva para crear "tokens literales":
YYUNDEF = 257,
ADD,
SUB,
MUL,
DIV,
POW,
FUNCTION,
IF,
ELSE,
FOR,
WHILE,
PRINT,
SEMICOLON,
COMPOSITE,
SQUOTE,
DERIVATIVE,
INTEGRATE,
BETWEEN,
AND_INT,
EVALUATE,
IN,
OPEN_BRACES,
OPEN_BRACKETS,
CLOSE_BRACES,
CLOSE_BRACKETS,
OPEN_PARENTHESIS,
CLOSE_PARENTHESIS,
ASSIGN,
EQUAL,
AND,
OR,
NOT,
ADD_ASSIGN,
INCREMENT,
SUB_ASSIGN,
DECREMENT,
MUL_ASSIGN,
DIV_ASSIGN,
DQUOTE,
COMMA,
COLON,
LESSER,
LESSER_EQUAL,
GREATER,
GREATER_EQUAL,
NOT_EQUAL,
VAR,
ERR,
TAYLOR,
ESCAPESTRING,
DOUBLE,
INTEGER,
ID
} TokenID;
/**
* Se definen las acciones a ejecutar sobre cada patrón hallado mediante el
* analizador léxico Flex. Este analizador solo puede identificar
* construcciones regulares, ya que utiliza un autómata finito determinístico
* (a.k.a. DFA), como mecanismo de escaneo y reconocimiento.
*/
TokenID IntegerPatternAction(const char * lexeme);
TokenID DoublePatternAction(const char * lexeme);
void IgnoredPatternAction(const char * lexeme);
TokenID UnknownPatternAction(const char * lexeme);
TokenID StringPatternAction(const char * lexeme);
TokenID EscapeStringPatternAction(const char * lexeme);
int IntegerPatternAction(const char * lexeme);
int DoublePatternAction(const char * lexeme);
void IgnoredPatternAction();
int UnknownPatternAction(const char * lexeme);
int StringPatternAction(char * lexeme);
int EscapeStringPatternAction(char * lexeme);
#endif

View File

@ -12,6 +12,7 @@
/* Dispone una variable global "yylineno" con el número de línea actual. */
%option yylineno
%option noinput nounput
/* Patrones reutilizables. */
crlf \r\n
@ -38,7 +39,6 @@ whitespace [ \f\n\r\t\v]
"print" { return PRINT; }
";" { return SEMICOLON; }
"o" { return COMPOSITE; }
"'" { return SQUOTE; }
"derivative" { return DERIVATIVE; }
"integrate" { return INTEGRATE; }
"int" { return INTEGRATE; }
@ -75,7 +75,6 @@ whitespace [ \f\n\r\t\v]
"\"" { return DQUOTE; }
"var" { return VAR; }
"err" { return ERR; }
"taylor" { return TAYLOR; }
{digit}+{decimal}{digit}+ { return DoublePatternAction(yytext); }
@ -85,7 +84,7 @@ whitespace [ \f\n\r\t\v]
\"{characters}+\" { return EscapeStringPatternAction(yytext); }
{whitespace} { IgnoredPatternAction(yytext); }
{whitespace} { IgnoredPatternAction(); }
. { return UnknownPatternAction(yytext); }

File diff suppressed because it is too large Load Diff

View File

@ -3,39 +3,77 @@
#include "../../backend/support/shared.h"
/**
* Se definen las acciones a ejecutar sobre cada regla de producción de la
* gramática. El objetivo de cada acción debe ser el de construir el nodo
* adecuado que almacene la información requerida en el árbol de sintaxis
* abstracta (i.e., el AST).
*/
// Programa.
int ProgramGrammarAction(const int value);
// Expresión.
int AdditionExpressionGrammarAction(const int leftValue, const int rightValue);
int SubtractionExpressionGrammarAction(const int leftValue, const int rightValue);
int MultiplicationExpressionGrammarAction(const int leftValue, const int rightValue);
int DivisionExpressionGrammarAction(const int leftValue, const int rightValue);
int FactorExpressionGrammarAction(const int value);
// Factores.
int ExpressionFactorGrammarAction(const int value);
int ConstantFactorGrammarAction(const int value);
// Constantes.
int IntegerConstantGrammarAction(const int value);
int DoubleConstantGrammarAction(const double value);
statement_t * EvaluateGrammarAction(evaluate_t * evaluate);
statement_t * IntegrateGrammarAction(integrate_t * integrate);
statement_t * DerivativeGrammarAction(derivative_t * derivative);
statement_t * IfGrammarAction(if_t * if_st);
statement_t * ForGrammarAction(for_t * for_st);
statement_t * WhileGrammarAction(while_t * while_st);
statement_t * PrintGrammarAction(print_t * print);
statement_t * DeclareVariableGrammarAction();
statement_t * AssignVariableGrammarAction();
Program * ProgramGrammarAction(Statement * statement);
Statement * StatementEvaluateGrammarAction(Evaluate * evaluate);
Statement * StatementIntegrateGrammarAction(Integrate * integrate);
Statement * StatementDerivativeGrammarAction(Derivative * derivative);
Statement * StatementIfGrammarAction(If * if_st);
Statement * StatementForGrammarAction(For * for_st);
Statement * StatementWhileGrammarAction(While * while_st);
Statement * StatementPrintGrammarAction(Print * print);
Statement * StatementDeclareFunctionGrammarAction(Function * function);
Statement * StatementAssignVariableGrammarAction(AssignVariable * variable);
Statement * StatementDeclareVariableGrammarAction(Variable * variable);
Statement * StatementsGrammarAction(Statement * stat1, Statement * stat2);
Expression * ExpressionOperatorAddGrammarAction(Expression * firstExpression, Expression * secondExpression);
Expression * ExpressionOperatorSubGrammarAction(Expression * firstExpression, Expression * secondExpression);
Expression * ExpressionOperatorMulGrammarAction(Expression * firstExpression, Expression * secondExpression);
Expression * ExpressionOperatorDivGrammarAction(Expression * firstExpression, Expression * secondExpression);
Expression * ExpressionOperatorPowGrammarAction(Expression * firstExpression, Expression * secondExpression);
Expression * ExpressionEvaluateGrammarAction(Evaluate * evaluate);
Expression * ExpressionDerivativeGrammarAction(Derivative * derivative);
Expression * ExpressionIntegrateGrammarAction(Integrate * integrate);
Expression * ExpressionPositiveConstantGrammarAction(double value);
Expression * ExpressionNegativeGrammarAction(Expression * exp);
Expression * ExpressionParenthesisGrammarAction(Expression * exp);
Expression * ExpressionIdGrammarAction(char * id);
Expression * ExpressionsGrammarAction(Expression * exp1, Expression * exp2);
Domain * DomainGreaterOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainLesserOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainLesserEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainGreaterEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainNotEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression);
Domain * DomainLesserLesserOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression, Expression * thirdExpression);
Domain * DomainLesserEqualLesserOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression, Expression * thirdExpression);
Domain * DomainLesserLesserEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression, Expression * thirdExpression);
Domain * DomainLesserEqualLesserEqualOperatorGrammarAction(Expression * firstExpression, Expression * secondExpression, Expression * thirdExpression);
Boolean * BooleanDomainGrammarAction(Domain * domain);
Boolean * BooleanAndGrammarAction(Boolean * left, Boolean * right);
Boolean * BooleanOrGrammarAction(Boolean * left, Boolean * right);
Boolean * NotBooleanAction(Boolean * notBoolean);
Boolean * BooleanGrammarAction(Boolean * boolen);
Function * DeclareFunctionGrammarAction(char * id, Function * func);
Function * FunctionsGrammarAction(Function * func1, Function * func2);
Function * CompositeFunctionGrammarAction(Composite * composite);
Function * ExpressionFunctionGrammarAction(Expression * expression);
Function * ExpressionDomainFunctionGrammarAction(Expression * expression, Domain * domain);
Composite * CompositeIdGrammarAction(char * id1, char * id2);
Composite * CompositeCompGrammarAction(char * id, Composite * composite);
Print * PrintExpressionGrammarAction(Expression * expression);
Print * PrintStringGrammarAction(char * string);
If * IfBlockGrammarAction(Boolean * boolean, Block * block);
If * IfElseBlockGrammarAction(Boolean * boolean, Block * block, Block * else_block);
While * WhileBlockGrammarAction(Boolean * boolean, Block * block);
For * ForBlockGrammarAction(Variable * init_variable, Boolean * boolean, AssignVariable * action_variable, Block * block);
For * ForBlockNoVarGrammarAction(Boolean * boolean, AssignVariable * action_variable, Block * block);
Block * BlockGrammarAction(Statement * statement);
Derivative * SimpleDerivativeGrammarAction(char * id, Expression * expression);
Derivative * GradedDerivativeGrammarAction(int grade, char * id, Expression * expression);
Derivative * ErroredDerivativeGrammarAction(Derivative * derivative, double error);
Integrate * IntegrateGrammarAction(char * id, Expression * lExp, Expression * rExp);
Integrate * ErroredIntegrateGrammarAction(Integrate * integrate, double error);
Evaluate * EvaluateGrammarAction(char * id, Expression * expression);
AssignVariable * AssignVariableAddGrammarAction(char * id, Expression * expression);
AssignVariable * AssignVariableSubGrammarAction(char * id, Expression * expression);
AssignVariable * AssignVariableMulGrammarAction(char * id, Expression * expression);
AssignVariable * AssignVariableDivGrammarAction(char * id, Expression * expression);
AssignVariable * AssignVariableIncGrammarAction(char * id);
AssignVariable * AssignVariableDecGrammarAction(char * id);
AssignVariable * AssignVariableGrammarAction(char * id, Expression * expression);
Variable * DeclareVariableGrammarAction(char * id);
Variable * DeclareValuedVariableGrammarAction(char * id, Expression * expression);
char * EscapedStringGrammarAction(char * str);
char * EscapedStringsGrammarAction(char * str1, char * str2);
#endif

View File

@ -1,42 +1,57 @@
%{
#include "bison-actions.h"
#include "nodes.h"
#include "../../backend/support/nodes.h"
%}
%union {
variable_t * variable;
function_t * function;
statement_t * statement;
expression_t * expression;
derivative_t * derivative;
evaluate_t * evaluate;
integrate_t * integrate;
algebraic_op_t * algebraic_op;
parenthesis_exp_t * parenthesis_exp;
boolean_t * boolean;
domain_t * domain;
Program * program;
Variable * variable;
If * if_st;
For * for_st;
While * while_st;
Print * print;
Function * function;
Statement * statement;
Expression * expression;
Derivative * derivative;
Evaluate * evaluate;
Integrate * integrate;
Boolean * boolean;
Domain * domain;
Block * block;
Composite * composite;
// NumArray * numArray;
AssignVariable * assignVariable;
int intNumber;
double doubleNumber;
char * string;
int token;
}
%type <variable> variable
%type <program> program
%type <variable> declare_variable
%type <function> function
%type <function> functions
%type <function> declare_function
%type <statement> statement
%type <assignVariable> assign_variable
%type <function> function functions declare_function
%type <statement> statement statements
%type <expression> expression
%type <derivative> derivative
%type <integrate> integrate
%type <evaluate> evaluate
%type <algebraic_op> algebraic_op
%type <parenthesis_exp> parenthesis_exp
%type <boolean> boolean
%type <domain> domain
%type <block> block
%type <while_st> while_statement
%type <if_st> if_statement
%type <for_st> for_statement
%type <composite> composite
%type <print> print
/* %type <numArray> numArrays numArray */
%type <doubleNumber> positive_constant
%type <string> escapeString
/* %type <intNumber> positive_constant */
%token <token> ADD
%token <token> SUB
@ -51,7 +66,6 @@
%token <token> PRINT
%token <token> SEMICOLON
%token <token> COMPOSITE
%token <token> SQUOTE
%token <token> DERIVATIVE
%token <token> INTEGRATE
%token <token> BETWEEN
@ -85,7 +99,6 @@
%token <token> NOT_EQUAL
%token <token> VAR
%token <intNumber> ERR
%token <token> TAYLOR
%token <string> ESCAPESTRING
%token <doubleNumber> DOUBLE
%token <intNumber> INTEGER
@ -99,89 +112,87 @@
%right NOT
%left MUL DIV AND OR
%left POW
%left SQUOTE
%%
program: statements { $$ = ProgramGrammarAction($1); }
;
statement: evaluate SEMICOLON { $$ = EvaluateGrammarAction($1); }
| integrate SEMICOLON { $$ = IntegrateGrammarAction($1); }
| derivative SEMICOLON { $$ = DerivativeGrammarAction($1); }
statement: evaluate SEMICOLON { $$ = StatementEvaluateGrammarAction($1); }
| integrate SEMICOLON { $$ = StatementIntegrateGrammarAction($1); }
| derivative SEMICOLON { $$ = StatementDerivativeGrammarAction($1); }
| if_statement { $$ = StatementIfGrammarAction($1); }
| declare_function SEMICOLON { $$ = StatementDeclareFunctionGrammarAction($1); }
| if_statement { $$ = IfGrammarAction($1); }
| for_statement { $$ = ForGrammarAction($1); }
| while_statement { $$ = WhileGrammarAction($1); }
| print SEMICOLON { $$ = PrintGrammarAction($1); }
| declare_variable SEMICOLON { $$ = VariableStatementGrammarAction($1); }
| assign_variable SEMICOLON { $$ = VariableStatementGrammarAction($1); }
| for_statement { $$ = StatementForGrammarAction($1); }
| while_statement { $$ = StatementWhileGrammarAction($1); }
| print SEMICOLON { $$ = StatementPrintGrammarAction($1); }
| declare_variable SEMICOLON { $$ = StatementDeclareVariableGrammarAction($1); }
| assign_variable SEMICOLON { $$ = StatementAssignVariableGrammarAction($1); }
;
expression: positive_constant { $$ = PositiveConstantGrammarAction($1) }
| evaluate { $$ = EvaluateGrammarAction($1) }
| integrate { $$ = IntegrateGrammarAction($1) }
| derivative { $$ = DerivativeGrammarAction($1) }
| ID { $$ = IdGrammarAction($1) }
| expression ADD expression { $$ = ExpressionOperatorGrammarAction($1, $2, $3) }
| expression SUB expression { $$ = ExpressionOperatorGrammarAction($1, $2, $3) }
| expression MUL expression { $$ = ExpressionOperatorGrammarAction($1, $2, $3) }
| expression DIV expression { $$ = ExpressionOperatorGrammarAction($1, $2, $3) }
| expression POW expression { $$ = ExpressionOperatorGrammarAction($1, $2, $3) }
| OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = ParenthesisExpressionGrammarAction($2) }
| SUB expression { $$ = NegativeExpressionGrammarAction($2) }
expression: positive_constant { $$ = ExpressionPositiveConstantGrammarAction($1); }
| evaluate { $$ = ExpressionEvaluateGrammarAction($1); }
| integrate { $$ = ExpressionIntegrateGrammarAction($1); }
| derivative { $$ = ExpressionDerivativeGrammarAction($1); }
| ID { $$ = ExpressionIdGrammarAction($1); }
| expression ADD expression { $$ = ExpressionOperatorAddGrammarAction($1, $3); }
| expression SUB expression { $$ = ExpressionOperatorSubGrammarAction($1, $3); }
| expression MUL expression { $$ = ExpressionOperatorMulGrammarAction($1, $3); }
| expression DIV expression { $$ = ExpressionOperatorDivGrammarAction($1, $3); }
| expression POW expression { $$ = ExpressionOperatorPowGrammarAction($1, $3); }
| OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = ExpressionParenthesisGrammarAction($2); }
| SUB expression { $$ = ExpressionNegativeGrammarAction($2); }
;
domain: expression LESSER expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression LESSER_EQUAL expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression GREATER_EQUAL expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression GREATER expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression EQUAL expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression NOT_EQUAL expression { $$ = DomainOneOptOperatorGrammarAction($1, $2, $3) }
| expression LESSER expression LESSER expression { $$ = DomainTwoOptOperatorGrammarAction($1, $2, $3, $4, $5) }
| expression LESSER_EQUAL expression LESSER expression { $$ = DomainTwoOptOperatorGrammarAction($1, $2, $3, $4, $5) }
| expression LESSER expression LESSER_EQUAL expression { $$ = DomainTwoOptOperatorGrammarAction($1, $2, $3, $4, $5) }
| expression LESSER_EQUAL expression LESSER_EQUAL expression { $$ = DomainTwoOptOperatorGrammarAction($1, $2, $3, $4, $5) }
domain: expression LESSER expression { $$ = DomainLesserOperatorGrammarAction($1, $3); }
| expression LESSER_EQUAL expression { $$ = DomainLesserEqualOperatorGrammarAction($1, $3); }
| expression GREATER_EQUAL expression { $$ = DomainGreaterEqualOperatorGrammarAction($1, $3); }
| expression GREATER expression { $$ = DomainGreaterOperatorGrammarAction($1, $3); }
| expression EQUAL expression { $$ = DomainEqualOperatorGrammarAction($1, $3); }
| expression NOT_EQUAL expression { $$ = DomainNotEqualOperatorGrammarAction($1, $3); }
| expression LESSER expression LESSER expression { $$ = DomainLesserLesserOperatorGrammarAction($1, $3, $5); }
| expression LESSER_EQUAL expression LESSER expression { $$ = DomainLesserEqualLesserOperatorGrammarAction($1, $3, $5); }
| expression LESSER expression LESSER_EQUAL expression { $$ = DomainLesserLesserEqualOperatorGrammarAction($1, $3, $5); }
| expression LESSER_EQUAL expression LESSER_EQUAL expression { $$ = DomainLesserEqualLesserEqualOperatorGrammarAction($1, $3, $5); }
;
boolean: domain { $$ = DomainGrammarAction($1) }
| boolean OR boolean { $$ = BooleanOperatorGrammarAction($1, $2, $3) }
| boolean AND boolean { $$ = BooleanOperatorGrammarAction($1, $2, $3) }
| OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS { $$ = $2 }
| NOT boolean { $$ = NotBooleanAction($2) }
boolean: domain { $$ = BooleanDomainGrammarAction($1); }
| boolean OR boolean { $$ = BooleanOrGrammarAction($1, $3); }
| boolean AND boolean { $$ = BooleanAndGrammarAction($1, $3); }
| OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS { $$ = BooleanGrammarAction($2); }
| NOT boolean { $$ = NotBooleanAction($2); }
;
positive_constant: DOUBLE { $$ = DoubleGrammarAction($1) }
| INTEGER { $$ = IntegerGrammarAction($1) }
positive_constant: DOUBLE { $$ = $1; }
| INTEGER { $$ = (double) $1; }
;
declare_function: FUNCTION ID ASSIGN function { $$ = DeclareFunctionGrammarAction($2, $4) }
| FUNCTION ID ASSIGN OPEN_BRACES functions CLOSE_BRACES { $$ = DeclareFunctionListGrammarAction($2, $5) }
declare_function: FUNCTION ID ASSIGN function { $$ = DeclareFunctionGrammarAction($2, $4); }
| FUNCTION ID ASSIGN OPEN_BRACES functions CLOSE_BRACES { $$ = DeclareFunctionGrammarAction($2, $5); }
;
function: expression { $$ = ExpressionFunctionGrammarAction($1) }
| expression COLON domain { $$ = ExpressionDomainFunctionGrammarAction($1, $3) }
| composite { $$ = CompositeFunctionGrammarAction($1) }
| taylor { $$ = TaylorFunctionGrammarAction($1) }
function: expression { $$ = ExpressionFunctionGrammarAction($1); }
| expression COLON domain { $$ = ExpressionDomainFunctionGrammarAction($1, $3); }
| composite { $$ = CompositeFunctionGrammarAction($1); }
;
functions: function { $$ = $1 }
| function COMMA functions { $$ = FunctionsGrammarAction($1, $3) }
functions: function { $$ = $1; }
| function COMMA functions { $$ = FunctionsGrammarAction($1, $3); }
;
composite: ID COMPOSITE ID { $$ = CompositeIdGrammarAction($1, $3) }
| composite COMPOSITE ID { $$ = CompositeCompGrammarAction($1, $3) }
composite: ID COMPOSITE ID { $$ = CompositeIdGrammarAction($1, $3); }
| ID COMPOSITE composite { $$ = CompositeCompGrammarAction($1, $3); }
;
expressions: expression { $$ = $1 }
| expression COMMA expressions { $$ = ExpressionsGrammarAction($1, $3) }
;
/* expressions: expression { $$ = $1; }
| expression COMMA expressions { $$ = ExpressionsGrammarAction($1, $3); }
; */
ids: ID { $$ = $1 }
/* ids: ID { $$ = $1 }
| ID COMMA ids { $$ = DoubleGrammarAction($1) }
;
; */
numArray: OPEN_BRACKETS expressions CLOSE_BRACKETS { $$ = DoubleGrammarAction($1) }
/* numArray: OPEN_BRACKETS expressions CLOSE_BRACKETS { $$ = $2; }
;
numArrays: numArray { $$ = DoubleGrammarAction($1) }
@ -189,87 +200,78 @@ numArrays: numArray
;
arrayNumArray: OPEN_BRACKETS numArrays CLOSE_BRACKETS { $$ = DoubleGrammarAction($1) }
;
; */
idArray: OPEN_BRACKETS ids CLOSE_BRACKETS { $$ = DoubleGrammarAction($1) }
;
/* idArray: OPEN_BRACKETS ids CLOSE_BRACKETS { $$ = DoubleGrammarAction($1) }
; */
escapeString: ESCAPESTRING { $$ = DoubleGrammarAction($1) }
| ESCAPESTRING ADD escapeString { $$ = DoubleGrammarAction($1) }
escapeString: ESCAPESTRING { $$ = EscapedStringGrammarAction($1); }
| ESCAPESTRING ADD escapeString { $$ = EscapedStringsGrammarAction($1, $3); }
;
/*
escapeStrings: escapeString { $$ = $1 }
| escapeString COMMA escapeStrings { $$ = DoubleGrammarAction($1) }
;
escapeStringArray: OPEN_BRACKETS escapeStrings CLOSE_BRACKETS { $$ = DoubleGrammarAction($1) }
;
evaluate: EVALUATE ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| EVALUATE ID IN numArray { $$ = DoubleGrammarAction($1) }
| ID OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| EVALUATE idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| EVALUATE idArray IN numArray { $$ = DoubleGrammarAction($1) }
| idArray OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
*/
evaluate: EVALUATE ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = EvaluateGrammarAction($2, $5); }
/* | EVALUATE ID IN numArray { $$ = DoubleGrammarAction($1) } */
| ID OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = EvaluateGrammarAction($1, $3); }
/* | EVALUATE idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) } */
/* | EVALUATE idArray IN numArray { $$ = DoubleGrammarAction($1) } */
/* | idArray OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) } */
;
integrate: INTEGRATE ID BETWEEN OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| INTEGRATE ID OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| INTEGRATE idArray BETWEEN OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| INTEGRATE idArray OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| integrate ERR positive_constant { $$ = DoubleGrammarAction($1) }
integrate: INTEGRATE ID BETWEEN OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = IntegrateGrammarAction($2, $5, $7); }
| INTEGRATE ID OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = IntegrateGrammarAction($2, $4, $6); }
/* | INTEGRATE idArray BETWEEN OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| INTEGRATE idArray OPEN_PARENTHESIS expression AND_INT expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) } */
| integrate ERR positive_constant { $$ = ErroredIntegrateGrammarAction($1, $3); }
;
squotes: SQUOTE { $$ = DoubleGrammarAction($1) }
| SQUOTE squotes { $$ = DoubleGrammarAction($1) }
print: PRINT OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = PrintExpressionGrammarAction($3); }
| PRINT OPEN_PARENTHESIS escapeString CLOSE_PARENTHESIS { $$ = PrintStringGrammarAction($3); }
;
print: PRINT OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = PrintExpression($3) }
| PRINT OPEN_PARENTHESIS escapeString CLOSE_PARENTHESIS { $$ = PrintExpression($3) }
statements: statement { $$ = $1; }
| statement statements { $$ = StatementsGrammarAction($1, $2); }
;
statements: statement { $$ = $1 }
| statement statements { $$ = StatementsGrammarAction($1, $2) }
derivative: DERIVATIVE ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = SimpleDerivativeGrammarAction($2, $5); }
| DERIVATIVE INTEGER ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = GradedDerivativeGrammarAction($2, $3, $6); }
/* | DERIVATIVE idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| DERIVATIVE INTEGER idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) } */
| derivative ERR positive_constant { $$ = ErroredDerivativeGrammarAction($1, $3); }
;
block: OPEN_BRACES statements CLOSE_BRACES { $$ = BlockGrammarAction($2); }
| statement { $$ = BlockGrammarAction($1); }
;
derivative: DERIVATIVE ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| DERIVATIVE INTEGER ID IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| ID squotes OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| DERIVATIVE idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| DERIVATIVE INTEGER idArray IN OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| idArray squotes OPEN_PARENTHESIS expression CLOSE_PARENTHESIS { $$ = DoubleGrammarAction($1) }
| derivative ERR positive_constant { $$ = DoubleGrammarAction($1) }
if_statement: IF OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block { $$ = IfBlockGrammarAction($3, $5); }
| IF OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block ELSE block { $$ = IfElseBlockGrammarAction($3, $5, $7); }
;
block: OPEN_BRACES statements CLOSE_BRACES { $$ = DoubleGrammarAction($1) }
| statement { $$ = DoubleGrammarAction($1) }
for_statement: FOR OPEN_PARENTHESIS declare_variable SEMICOLON boolean SEMICOLON assign_variable CLOSE_PARENTHESIS block { $$ = ForBlockGrammarAction($3, $5, $7, $9); }
| FOR OPEN_PARENTHESIS SEMICOLON boolean SEMICOLON assign_variable CLOSE_PARENTHESIS block { $$ = ForBlockNoVarGrammarAction($4, $6, $8); }
;
if_statement: IF OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block { $$ = IfBlockGrammarAction($3, $5) }
| IF OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block ELSE block { $$ = IfElseBlockGrammarAction($3, $5, $7) }
while_statement: WHILE OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block { $$ = WhileBlockGrammarAction($3, $5); }
;
for_statement: FOR OPEN_PARENTHESIS declare_variable SEMICOLON boolean SEMICOLON assign_variable CLOSE_PARENTHESIS block { $$ = DoubleGrammarAction($1) }
| FOR OPEN_PARENTHESIS SEMICOLON boolean SEMICOLON assign_variable CLOSE_PARENTHESIS block { $$ = DoubleGrammarAction($1) }
declare_variable: VAR ID { $$ = DeclareVariableGrammarAction($2); }
| VAR ID ASSIGN expression { $$ = DeclareValuedVariableGrammarAction($2, $4); }
;
taylor: TAYLOR INTEGER ID { $$ = DoubleGrammarAction($1) }
;
while_statement: WHILE OPEN_PARENTHESIS boolean CLOSE_PARENTHESIS block { $$ = WhileBlockGrammarAction($3, $5) }
;
declare_variable: VAR ID { $$ = DoubleGrammarAction($1) }
| declare_variable ASSIGN expression { $$ = DoubleGrammarAction($1) }
;
assign_variable: ID ADD_ASSIGN expression { $$ = DoubleGrammarAction($1) }
| ID SUB_ASSIGN expression { $$ = DoubleGrammarAction($1) }
| ID MUL_ASSIGN expression { $$ = DoubleGrammarAction($1) }
| ID DIV_ASSIGN expression { $$ = DoubleGrammarAction($1) }
| ID INCREMENT { $$ = DoubleGrammarAction($1) }
| ID DECREMENT { $$ = DoubleGrammarAction($1) }
| ID ASSIGN expression { $$ = DoubleGrammarAction($1) }
assign_variable: ID ADD_ASSIGN expression { $$ = AssignVariableAddGrammarAction($1, $3); }
| ID SUB_ASSIGN expression { $$ = AssignVariableSubGrammarAction($1, $3); }
| ID MUL_ASSIGN expression { $$ = AssignVariableMulGrammarAction($1, $3); }
| ID DIV_ASSIGN expression { $$ = AssignVariableDivGrammarAction($1, $3); }
| ID INCREMENT { $$ = AssignVariableIncGrammarAction($1); }
| ID DECREMENT { $$ = AssignVariableDecGrammarAction($1); }
| ID ASSIGN expression { $$ = AssignVariableGrammarAction($1, $3); }
;
%%

View File

@ -1,35 +1,80 @@
#include "backend/code-generation/generator.h"
#include "backend/semantic-analysis/analyzer.h"
#include "backend/free-tree/free-tree.h"
#include "backend/support/logger.h"
#include "backend/support/shared.h"
#include "frontend/syntactic-analysis/bison-parser.h"
#include <stdio.h>
#include <math.h>
#include <getopt.h>
CompilerState state;
const int main(const int argumentCount, const char ** arguments) {
int main(int argc, char ** argv) {
// #ifdef YYDEBUG
// yydebug = 1;
// #endif
state.result = 0;
state.succeed = false;
for (int i = 0; i < argumentCount; ++i) {
LogInfo("Argumento %d: '%s'", i, arguments[i]);
char * outputFile = NULL;
if (argc > 1) {
FILE * file = fopen(argv[1], "r+");
if (file == NULL) {
perror("Error abriendo el archivo");
abort();
}
yyin = file;
for (int i = 1; i < argc; ++i) {
argv[i] = argv[i+1];
}
argc--;
int c = getopt(argc, argv, "ho:");
switch (c) {
case 'h':
LogInfo("Suckerberg");
exit(EXIT_SUCCESS);
case 'o':
outputFile = optarg;
break;
default:
break;
}
}
LogInfo("Compilando...\n");
const int result = yyparse();
InitializeMallocTable();
int result = yyparse();
switch (result) {
case 0:
if (state.succeed) {
LogInfo("La compilacion fue exitosa.");
// Generator(state.result);
if (!Analyze(state.program)) {
result = EXIT_FAILURE;
break;
}
FILE * file = fopen(outputFile != NULL ? outputFile : "bottler.m", "w+");
if (file == NULL) {
perror("Error abriendo el archivo");
result = 1;
break;
}
Generator(state.program, file);
if (fclose(file) == EOF) {
perror("Error cerrando el archivo");
result = EXIT_FAILURE;
break;
}
}
else {
LogError("Se produjo un error en la aplicacion.");
return -1;
result = EXIT_FAILURE;
break;
// return -1;
}
break;
case 1:
@ -41,6 +86,7 @@ const int main(const int argumentCount, const char ** arguments) {
default:
LogError("Error desconocido mientras se ejecutaba el analizador Bison (codigo %d).", result);
}
LogInfo("Fin.");
FreeMallocTable();
return result;
}