From 729cbf9a50d85a5320bccc22de094a4762116ed0 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Thu, 11 Mar 2021 17:42:14 +0100 Subject: [PATCH] First draft --- main.py | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++--- sample.txt | 12 +++-- 2 files changed, 142 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index f7619c3..e116cfa 100644 --- a/main.py +++ b/main.py @@ -1,16 +1,144 @@ + +rules_dict = {} +terminals_set = set() + + def parse(lines): lines = [line.strip() for line in lines] - lines = [line.split("->") for line in lines] - rules = [(line[0], line[1].strip().split(" ")) for line in lines] + lines = [line.split(":") for line in lines] + rules = [(line[0].strip(), line[1].strip().split(" ")) for line in lines] + for r in rules: + for right_element in r[1]: + if len(right_element) > 0 and not right_element[0].isupper(): + terminals_set.add(right_element) + + for i in range(0, len(rules)): + left = rules[i][0] + if left not in rules_dict: + rules_dict[left] = 0 + + print_includes() + print_util() + print_declarations() + print_terminal_rules() print_rules(rules) + print_main(rules) + # print(rules) + # print(rules_dict) + # print(terminals_set) + + +def print_declarations(): + for key in rules_dict: + print(f"int parse_{key}(char* word, int pos);") + + +def print_includes(): + print(""" +#include +#include +""") + + +def print_util(): + print(""" +void print_with_indent(int indent, char * string) +{ + printf("%*s%s", indent, "", string); +} +""") + +# int str_split(char* str, char token) { +# char* result = ""; +# for (int i = 0; i < sizeof(str); i++) +# { +# result[ +# } +# return result; +# } + +def print_main(rules): + axiom = get_code(rules[0][0]) + print(f""" +int main(int argc, char* argv[]) {{ + char* word; + if (argc >= 2) + word = argv[1]; + else + word = ""; + int value = parse_{axiom}(word, 0); + printf("%d\\n", value); + if (value == strlen(word)) {{ + printf("OK\\n"); + }} else {{ + printf("KO\\n"); + }} +}} +""") def print_rules(rules): - for rule in rules: - print("void parse_%s(...) {" % rule[0]) + print_unit_rules(rules) + print_global_rules() + + +def print_unit_rules(rules): + for i in range(0, len(rules)): + rule = rules[i] + left = rule[0] + rules_dict[left] += 1 + code = get_code(left) + print(f"""int parse_{code}{rules_dict[left]}(char* word, int pos) {{ + int totalCharParsed = 0; + int nbCharParsed = 0; + printf("Entering {code}{rules_dict[left]}\\n"); + """) for element in rule[1]: - print(" parse_%s(...);" % element) - print("}") + elem_code = get_code(element) + print(f""" nbCharParsed = parse_{elem_code}(word, pos + totalCharParsed); + if (!nbCharParsed) {{ + printf("Fail {elem_code} in {code}{rules_dict[left]}\\n"); + return 0; + }} + totalCharParsed += nbCharParsed;""") + print(f""" + printf("Success {code}{rules_dict[left]}\\n"); + return totalCharParsed; +}}""") + + +def print_global_rules(): + for (key, value) in rules_dict.items(): + code = get_code(key) + print(f"""int parse_{code}(char* word, int pos) {{ + int nbCharParsed = 0; + printf("Entering {key}\\n");""") + for i in range(1, value + 1): + print(f""" + nbCharParsed = parse_{code}{i}(word, pos); + if (nbCharParsed) {{ + return nbCharParsed; + }}""") + print(""" + return 0; +}""") + + +def get_code(s): + return ord(s) if len(s) == 1 and ((s < "A" or s > "Z") and (s < "a" or s > "z")) else s + + +def print_terminal_rules(): + for t in terminals_set: + code = get_code(t) + print(f"""int parse_{code}(char* word, int pos) {{ + if (strcomp(word[pos], "{t}") == 0) {{ + print_with_indent(pos, "{code}\\n"); + return 1; + }} else {{ + return 0; + }} +}}""") if __name__ == '__main__': diff --git a/sample.txt b/sample.txt index 59bd4f9..7b2fb0c 100644 --- a/sample.txt +++ b/sample.txt @@ -1,4 +1,8 @@ -T -> S u S -T -> x S y -S -> a S b -S -> \ No newline at end of file +S : int +S : string +S : { Assoc } +Assoc : KeyVal AssocBis +Assoc : +AssocBis : , KeyVal AssocBis +AssocBis : +KeyVal : id = S