From e70feb8ccefed05878cb3f714ea34ad8f8d8ddfa Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 19 Nov 2017 14:34:00 +0100 Subject: [PATCH] Syntactic analysis fully working implementation. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- lexer/Makefile | 7 +- lexer/lexical_analyzer.c | 4 +- lexer/main.c | 10 +- lexer/print_helper.c | 24 ++++- lexer/print_helper.h | 4 + lexer/syntactic_analyzer.c | 210 ++++++++++++++++++++++++++----------- lexer/syntactic_analyzer.h | 4 +- 7 files changed, 186 insertions(+), 77 deletions(-) diff --git a/lexer/Makefile b/lexer/Makefile index ba41375..bc63f97 100644 --- a/lexer/Makefile +++ b/lexer/Makefile @@ -12,7 +12,8 @@ # Automatic dependencies code from: # http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#tldr BINARY_NAME=lexer -BUILD_TYPE=debug +#BUILD_TYPE=debug +BUILD_TYPE=release # ==================================== # DO NOT CHANGE STUFF BEYOND THIS LINE @@ -29,16 +30,18 @@ STD_FLAG = -std=c11 ifeq ($(BUILD_TYPE),debug) BUILDDIR := .build/debug DEBUG_FLAG = -g +DEBUG = 1 STRIP_FLAG = OPTI_FLAG = -O0 else BUILDDIR := .build/release DEBUG_FLAG = +DEBUG = 0 STRIP_FLAG = -s OPTI_FLAG = -O3 endif -CFLAGS := $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG) +CFLAGS := -DDEBUG=$(DEBUG) $(CFLAGS) $(WARN_FLAGS) $(STD_FLAG) $(OPTI_FLAG) $(DEBUG_FLAG) LDFLAGS := $(LDFLAGS) $(STRIP_FLAG) OBJDIR := $(BUILDDIR)/objs diff --git a/lexer/lexical_analyzer.c b/lexer/lexical_analyzer.c index 905647e..42ab960 100644 --- a/lexer/lexical_analyzer.c +++ b/lexer/lexical_analyzer.c @@ -200,12 +200,12 @@ FIN: error: if (tokenType == MOT || tokenType == MOTCLE) { - wpr_error(L"%s error with token type: %s and value: %ls\n", + fwprintf(stderr, L"%s error with token type: %s and value: %ls\n", __func__, tokenTypestr[tokenType], token[tokenFound].value); } else { - wpr_error(L"%s error with token type: %s\n", + fwprintf(stderr, L"%s error with token type: %s\n", __func__, tokenTypestr[tokenType]); } diff --git a/lexer/main.c b/lexer/main.c index d3f086e..ca385b3 100644 --- a/lexer/main.c +++ b/lexer/main.c @@ -13,11 +13,7 @@ void do_lexical_analysis() { c = fgetwc(source); // lecture du premier caractere do { scanner(); - if (tokenType == MOT || tokenType == MOTCLE) { - fwprintf(target, L"%20s: %ls\n", tokenTypestr[tokenType], token[tokenFound].value); - } else { - fwprintf(target, L"%20s\n", tokenTypestr[tokenType]); - } + wprint_token(); token[tokenFound].type = tokenTypestr[tokenType]; tokenFound++; } while (tokenType != FIN); // tant que la fin du fichier n'est pas atteinte @@ -25,9 +21,7 @@ void do_lexical_analysis() { void do_syntactic_analysis() { c = fgetwc(source); // lecture du premier caractere - do { - analyze_AXIOME(); - } while (tokenType != FIN); + analyze_AXIOME(); } void print_usage(const char* name) { diff --git a/lexer/print_helper.c b/lexer/print_helper.c index d5ca8f0..23684d5 100644 --- a/lexer/print_helper.c +++ b/lexer/print_helper.c @@ -2,7 +2,9 @@ #include #include -void pr_warning(const char *format, ...) { +#include "global_vars.h" + +void pr_warning(const char* format, ...) { va_list args; va_start(args, format); @@ -18,6 +20,18 @@ void pr_error(const char *format, ...) { va_end(args); } +#if DEBUG +void pr_debug(const char *format, ...) { + va_list args; + + va_start(args, format); + fprintf(stderr, format, args); + va_end(args); +} +#else +void pr_debug(const char *format, ...); +#endif /* DEBUG */ + void wpr_warning(const wchar_t *format, ...) { va_list args; @@ -33,3 +47,11 @@ void wpr_error(const wchar_t *format, ...) { fwprintf(stderr, format, args); va_end(args); } + +void wprint_token() { + if (tokenType == MOT || tokenType == MOTCLE) { + fwprintf(target, L"%20s: %ls\n", tokenTypestr[tokenType], token[tokenFound].value); + } else { + fwprintf(target, L"%20s\n", tokenTypestr[tokenType]); + } +} diff --git a/lexer/print_helper.h b/lexer/print_helper.h index e92cc84..5daaa35 100644 --- a/lexer/print_helper.h +++ b/lexer/print_helper.h @@ -4,7 +4,11 @@ void pr_warning(const char *format, ...); void pr_error(const char *format, ...); +void pr_debug(const char *format, ...); + void wpr_warning(const wchar_t *format, ...); void wpr_error(const wchar_t *format, ...); +void wprint_token(); + #endif /* PRINT_HELPER_H_ */ diff --git a/lexer/syntactic_analyzer.c b/lexer/syntactic_analyzer.c index e23c130..2d3880f 100644 --- a/lexer/syntactic_analyzer.c +++ b/lexer/syntactic_analyzer.c @@ -2,121 +2,207 @@ #include #include +#include #include "global_vars.h" #include "lexical_analyzer.h" +#include "print_helper.h" + +#define PRINT_TOKEN 0 /* Syntactic analyzer functions implementation */ enum TokenType tokenType; -static bool analyze_TEXT() { - bool rtval = true; +static void analyze_TEXT() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif if (tokenType == MOT) { scanner(); - rtval = analyze_TEXT(); + #if PRINT_TOKEN + wprint_token(); + #endif + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); } else if (tokenType != MOTCLE && tokenType != NPARA && tokenType != SECTION && \ tokenType != SSECTION && tokenType != FIN) { - rtval = false; + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_P() { - bool rtval = true; +static void analyze_P() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif if (tokenType == NPARA) { scanner(); + #if PRINT_TOKEN + wprint_token(); + #endif + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; if (tokenType == MOT) { scanner(); - rtval = analyze_TEXT(); - rtval = analyze_P(); + #if PRINT_TOKEN + wprint_token(); + #endif + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); + analyze_P(); + } else if (tokenType != SECTION && tokenType != SSECTION && tokenType != FIN) { + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } } else if (tokenType != SECTION && tokenType != SSECTION && tokenType != FIN) { - rtval = false; + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_HEAD() { - bool rtval = true; +static void analyze_HEAD() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif if (tokenType == MOTCLE) { scanner(); - rtval = analyze_TEXT(); + #if PRINT_TOKEN + wprint_token(); + #endif + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); if (tokenType == MOTCLE) { scanner(); - rtval = analyze_TEXT(); - } else { - rtval = false; + #if PRINT_TOKEN + wprint_token(); + #endif /* PRINT_TOKEN */ + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); + } else if (tokenType != NPARA && tokenType != SECTION && tokenType != FIN) { + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - } else { - rtval = false; + } else if (tokenType != NPARA && tokenType != SECTION && tokenType != FIN) { + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_H1() { - bool rtval = true; +static void analyze_H1() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif if (tokenType == SECTION) { scanner(); - rtval = analyze_TEXT(); - } else { - rtval = false; + #if PRINT_TOKEN + wprint_token(); + #endif /* PRINT_TOKEN */ + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_H2() { - bool rtval = true; +static void analyze_H2() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif if (tokenType == SSECTION) { scanner(); - rtval = analyze_TEXT(); - } else { - rtval = false; + #if PRINT_TOKEN + wprint_token(); + #endif /* PRINT_TOKEN */ + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_TEXT(); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_S2() { - bool rtval = true; - if (analyze_H2()) { - rtval = analyze_P(); - rtval = analyze_S2(); +static void analyze_S2() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif + if (tokenType == SSECTION) { + analyze_H2(); + analyze_P(); + analyze_S2(); } else if (tokenType != SECTION && tokenType != FIN) { - rtval = false; - } else { - rtval = false; + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_S1() { - bool rtval = true; - if (analyze_H1()) { - rtval = analyze_P(); - rtval = analyze_S2(); - rtval = analyze_S1(); +static void analyze_S1() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif + if (tokenType == SECTION) { + analyze_H1(); + analyze_P(); + analyze_S2(); + analyze_S1(); } else if (tokenType != FIN) { - rtval = false; - } else { - rtval = false; + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -static bool analyze_BODY() { - bool rtval = true; - rtval = analyze_P(); - rtval = analyze_S1(); - return rtval; +static void analyze_BODY() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif + analyze_P(); + analyze_S1(); + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } -bool analyze_AXIOME() { - bool rtval = true; +void analyze_AXIOME() { + #if DEBUG + fprintf(stdout, "entering %s\n", __func__); + #endif scanner(); - rtval = analyze_HEAD(); - rtval = analyze_BODY(); + /* print the lexical analysis result */ + #if PRINT_TOKEN + wprint_token(); + #endif /* PRINT_TOKEN */ + token[tokenFound].type = tokenTypestr[tokenType]; + tokenFound++; + analyze_HEAD(); + analyze_BODY(); if (tokenType != FIN) { - rtval = false; + fprintf(stderr, "%s follows error on %s\n", __func__, tokenTypestr[tokenType]); + exit(EXIT_FAILURE); } - return rtval; + fprintf(stdout, "successful syntactic analysis\n"); + #if DEBUG + fprintf(stdout, "leaving %s\n", __func__); + #endif } diff --git a/lexer/syntactic_analyzer.h b/lexer/syntactic_analyzer.h index 675873c..9259841 100644 --- a/lexer/syntactic_analyzer.h +++ b/lexer/syntactic_analyzer.h @@ -1,8 +1,8 @@ #ifndef SYNTACTIC_ANALYZER_H_ #define SYNTACTIC_ANALYZER_H_ -/* Syntactic analyser functions declarations */ +/* Syntactic analyzer functions declarations */ -bool analyze_AXIOME(); +void analyze_AXIOME(); #endif /* SYNTACTIC_ANALYZER_H_ */ -- 2.34.1