added inc and src dir and refactored utility functions

This commit is contained in:
Sven Vogel 2023-11-29 13:57:06 +01:00
parent af2106a48f
commit 6d6ff3e78d
8 changed files with 165 additions and 69 deletions

1
ast-lex-yacc/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build/

View File

@ -1,6 +1,8 @@
BUILDDIR = build
TARGET_SRC = main
OUT = main
SRC_DIR = src
INCLUDE_DIR = inc
build: mkdir main
all: mkdir main run
@ -12,15 +14,15 @@ run: # run binary
./$(BUILDDIR)/main
main: lex.yy.c yacc.yy.c
cc $(BUILDDIR)/yacc.yy.c $(BUILDDIR)/lex.yy.c -o $(BUILDDIR)/$(TARGET_SRC) -lfl
cc -Wall -I$(INCLUDE_DIR) $(SRC_DIR)/extio.c $(BUILDDIR)/yacc.yy.c $(BUILDDIR)/lex.yy.c -o $(BUILDDIR)/$(OUT)
# generate c file for lex
lex.yy.c:
flex -o $(BUILDDIR)/lex.yy.c $(TARGET_SRC).l
flex -o $(BUILDDIR)/lex.yy.c $(SRC_DIR)/lexer.l
# generate c file for yacc
yacc.yy.c:
yacc -d -o $(BUILDDIR)/yacc.yy.c $(TARGET_SRC).y
yacc -d -o $(BUILDDIR)/yacc.yy.c $(SRC_DIR)/parser.y
clean: # wipe the build directory
rm -f $(BUILDDIR)/*

18
ast-lex-yacc/inc/extio.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _EXTIO_H_
#define _EXTIO_H_
#include <stdarg.h>
#include <stdio.h>
// define different ANSI format strings
extern const char *DEBUG;
extern const char *INFO;
extern const char *WARN;
extern const char *ERROR;
/**
* prints a notification string to standard out
*/
int notify(const char *type, const char *format, ...);
#endif

View File

@ -1,37 +0,0 @@
%option noyywrap
%{
#include <stdio.h>
#include "yacc.yy.h"
#define YYDEBUG 1
int yyLineNumber = 1;
%}
%%
\n yyLineNumber++;
0|[1-9][0-9]* return(Number); // integer numbers
"VAR"|"var" return(Variable);
"INT"|"int" return(Integer);
[a-zA-Z]+ return(Ident);
"," return(',');
":" return(':');
";" return(';');
"+" return('+');
"-" return('-');
"(" return('(');
")" return(')');
[ \t]
. print_stdout("unknown Symbol");
%%
/*
int main()
{
printf("Programm eingeben: \n");
yylex();
return 0;
}
*/
int print_stdout(char token[]) {
printf("\nFLEX/[INF] >>> Token (%d) AS %s ```%s```\n", yyLineNumber, token, yytext);
}

View File

@ -1,28 +0,0 @@
%{
#include <stdio.h>
extern int yylineno;
%}
%token Variable
%token Integer
%token Ident
%token Number
%%
program: decllist exprlist;
decllist: decl ';' | decllist decl ';' | /* empty */ | error ';' { yyerror(" im Deklarationsteil\n"); };
decl: Variable idlist ':' type;
idlist: Ident | idlist ',' Ident;
type: Integer;
exprlist: /* empty */ ;
%%
int main() {
printf("Bitte geben Sie ein Program ein: \n");
yyparse();
return 0;
}
int yyerror(char *s) {
printf("YACC/[ERR] >>> Failed parsing grammar (%d): ```%s```", yylineno, s);
}

49
ast-lex-yacc/src/extio.c Normal file
View File

@ -0,0 +1,49 @@
#include "extio.h"
#define COLORS
extern int yylineno;
#ifdef COLORS
#define NORMAL "\x1b[0m"
#define GREEN "\33[32m"
#define RED "\33[31m"
#define YELLOW "\33[33m"
#define BLUE "\33[34m"
#define BOLD "\033[1m"
#else
#define NORMAL ""
#define GREEN ""
#define RED ""
#define YELLOW ""
#define BLUE ""
#define BOLD ""
#endif
// define different ANSI format strings
const char *DEBUG = GREEN "DEBUG" NORMAL;
const char *INFO = BLUE "INFO" NORMAL;
const char *WARN = BOLD "" YELLOW "WARNING" NORMAL;
const char *ERROR = RED "ERROR" NORMAL;
int notify(const char *type, const char *format, ...) {
int char_count = 0;
// print header
char_count += printf("%s in line %d: " BOLD, type, yylineno);
// print formatted variable arguments
va_list args;
va_start(args, format);
char_count += vprintf(format, args);
va_end(args);
// print tail
char_count += printf(NORMAL "\n\torigin: YACC type: SYNTAX\n\n");
return char_count;
}

30
ast-lex-yacc/src/lexer.l Normal file
View File

@ -0,0 +1,30 @@
%option noyywrap
%{
#include <stdio.h>
#include <stdlib.h>
#include "yacc.yy.h"
#include "extio.h"
int yyLineNumber = 1;
int yylex();
%}
%%
\n yyLineNumber++;
0|[1-9][0-9]* { yylval.num = atoi(yytext); return(Number); } // integer numbers
"VAR"|"var" return(Variable);
"INT"|"int" return(Integer);
[a-zA-Z]+ { yylval.str = strdup(yytext); return(Ident); }; // FIXME: unfreed heap allocation
"," return(',');
":" return(':');
";" return(';');
"+" return(Operator);
"-" return(Operator);
"*" return(Operator);
"/" return(Operator);
"(" return('(');
")" return(')');
[ \t]
. notify(WARN, "unknown Symbol: %s", yytext);
%%

61
ast-lex-yacc/src/parser.y Normal file
View File

@ -0,0 +1,61 @@
%{
#define COLORS
#include <stdio.h>
#include "extio.h"
extern int yylineno;
int yyerror(char*);
int yylex();
%}
%union {
char *str;
int num;
}
%token Variable
%token Integer
%token <str> Ident
%token <num> Number
%token Operator
%%
program: decllist exprlist;
decllist: decl ';'
| decllist decl ';'
| /* empty */ |
error ';' { notify(ERROR, "in declaration"); };
decl: Variable idlist ':' type { notify(DEBUG, "declaration found"); };
idlist: Ident { notify(DEBUG, "identifier found"); };
| idlist ',' Ident;
type: Integer { notify(DEBUG, "type found"); };
exprlist: expr ';' { notify(DEBUG, "expression discovered"); }
| exprlist expr ';';
expr: '(' expr Operator expr ')'
| error expr Operator expr ')' { notify(ERROR, "missing open parenthesis"); }
| '(' error Operator expr ')' { notify(ERROR, "error in left hand expression"); }
| '(' expr error expr ')' { notify(ERROR, "expected operator in expression"); }
| '(' expr Operator error ')' { notify(ERROR, "error in right hand expression"); }
| '(' expr Operator expr error { notify(ERROR, "missing closing parenthesis"); }
| Ident { notify(DEBUG, "identifier: %s", $1); }
| Number { notify(DEBUG, "number: %08x", yyval.num); }
| error ';' { notify(ERROR, "in expression"); };
%%
int main() {
printf("Bitte geben Sie ein Program ein: \n");
yyparse();
return 0;
}
int yyerror(char *s) {
return 0;
}