diff --git a/labs/03/lexer.l b/labs/03/lexer.l new file mode 100644 index 0000000..7625e55 --- /dev/null +++ b/labs/03/lexer.l @@ -0,0 +1,40 @@ +%{ +#include "y.tab.h" +#include +#include +#include +%} + +%{ +int line_number = 1; +%} + +%% +a|the {yylval.sval = strdup(yytext); return ARTICLE;} +boy|girl|flower {yylval.sval = strdup(yytext); return NOUN;} +touches|likes|sees {yylval.sval = strdup(yytext); return VERB;} +with {yylval.sval = strdup(yytext); return PREP;} + +[ \t]+ /* Ignorar espacios en blanco y tabulaciones */ + +^[ \t]*\n /* Ignorar líneas en blanco */ + +\n { line_number++; return '\n'; } + +. { fprintf(stderr, "Error: Caracter inesperado '%s' en la línea %d\n", yytext, line_number); } + +%% + +// Función auxiliar para liberar la memoria asignada a las cadenas. +void yystring_free(char* str) { + if (str != NULL) { + free(str); + } +} + +// Función principal de análisis léxico. +int yylex() { + int token = yylex_aux(); // Obtener el token del analizador léxico generado por Flex. + yystring_free(yylval.sval); // Liberar memoria asignada a las cadenas después de su uso. + return token; +} diff --git a/labs/03/parser.y b/labs/03/parser.y new file mode 100644 index 0000000..44853fc --- /dev/null +++ b/labs/03/parser.y @@ -0,0 +1,71 @@ +%{ +#include +#include +#include + +extern int line_number; +extern FILE *yyin; +extern int yylex(); +void yyerror(const char *s); +%} + +%union { + char *sval; +} + +%token ARTICLE NOUN VERB PREP + +%% + +/* Regla inicial */ +start: sentences '\n' { printf("Sentence is valid.\n"); } + +/* Producción recursiva para manejar múltiples oraciones */ +sentences: /* empty */ + | sentences sentence '\n' { printf("Sentence is valid.\n"); } + +/* Definición de una oración */ +sentence: NOUN_PHRASE VERB_PHRASE { printf("Complete sentence: %s %s\n", $1, $2); } + | NOUN_PHRASE { printf("Noun phrase: %s\n", $1); } + | VERB_PHRASE { printf("Verb phrase: %s\n", $1); } +; + +/* Definición de una frase nominal */ +NOUN_PHRASE: ARTICLE NOUN { $$ = strdup(strcat($1, $2)); } + | ARTICLE NOUN PREP_PHRASE { $$ = strdup(strcat(strcat($1, $2), $3)); } +; + +/* Definición de una frase verbal */ +VERB_PHRASE: VERB { $$ = strdup($1); } + | VERB NOUN_PHRASE { $$ = strdup(strcat($1, $2)); } +; + +/* Definición de una frase preposicional */ +PREP_PHRASE: PREP NOUN_PHRASE { $$ = strdup(strcat($1, $2)); } +; + +%% + +/* Función de manejo de errores */ +void yyerror(const char *s) { + fprintf(stderr, "Syntax error at line %d: %s\n", line_number, s); +} + +/* Función principal */ +int main(int argc, char **argv) { + if (argc == 2) { + if (!(yyin = fopen(argv[1], "r"))) { + perror("Error al abrir el archivo: "); + return 1; + } + + yyparse(); + fclose(yyin); + + } else { + fprintf(stderr, "Usage: %s filename\n", argv[0]); + return 1; + } + + return 0; +}