Parse input with a space between each terminal + other improvements
This commit is contained in:
parent
2ffc6c5111
commit
22583e6894
2 changed files with 41 additions and 27 deletions
61
main.py
61
main.py
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
rules_dict = {}
|
rules_dict = {}
|
||||||
terminals_set = set()
|
terminals_set = set()
|
||||||
|
|
||||||
|
|
||||||
def parse(lines):
|
def parse(lines):
|
||||||
lines = [line.strip() for line in lines]
|
lines = [line.strip() for line in lines]
|
||||||
lines = [line.split(":") for line in lines]
|
lines = [line.split(":") for line in lines]
|
||||||
|
@ -20,6 +18,7 @@ def parse(lines):
|
||||||
print_includes()
|
print_includes()
|
||||||
print_util()
|
print_util()
|
||||||
print_declarations()
|
print_declarations()
|
||||||
|
print("// ---- Functions to parse terminals ----")
|
||||||
print_terminal_rules()
|
print_terminal_rules()
|
||||||
print_rules(rules)
|
print_rules(rules)
|
||||||
print_main(rules)
|
print_main(rules)
|
||||||
|
@ -31,19 +30,18 @@ def parse(lines):
|
||||||
def print_declarations():
|
def print_declarations():
|
||||||
for key in rules_dict:
|
for key in rules_dict:
|
||||||
print(f"int parse_{key}(char* word, int pos);")
|
print(f"int parse_{key}(char* word, int pos);")
|
||||||
|
print()
|
||||||
|
|
||||||
def print_includes():
|
def print_includes():
|
||||||
print("""
|
print("""\
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
def print_util():
|
def print_util():
|
||||||
print("""
|
print("""\
|
||||||
void print_with_indent(int indent, char * string)
|
void print_with_indent(int indent, char * string) {
|
||||||
{
|
|
||||||
printf("%*s%s", indent, "", string);
|
printf("%*s%s", indent, "", string);
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
@ -59,7 +57,7 @@ void print_with_indent(int indent, char * string)
|
||||||
|
|
||||||
def print_main(rules):
|
def print_main(rules):
|
||||||
axiom = get_code(rules[0][0])
|
axiom = get_code(rules[0][0])
|
||||||
print(f"""
|
print(f"""\
|
||||||
int main(int argc, char* argv[]) {{
|
int main(int argc, char* argv[]) {{
|
||||||
char* word;
|
char* word;
|
||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
|
@ -68,7 +66,7 @@ int main(int argc, char* argv[]) {{
|
||||||
word = "";
|
word = "";
|
||||||
int value = parse_{axiom}(word, 0);
|
int value = parse_{axiom}(word, 0);
|
||||||
printf("%d\\n", value);
|
printf("%d\\n", value);
|
||||||
if (value == strlen(word)) {{
|
if (value == strlen(word) + 1) {{
|
||||||
printf("OK\\n");
|
printf("OK\\n");
|
||||||
}} else {{
|
}} else {{
|
||||||
printf("KO\\n");
|
printf("KO\\n");
|
||||||
|
@ -78,7 +76,9 @@ int main(int argc, char* argv[]) {{
|
||||||
|
|
||||||
|
|
||||||
def print_rules(rules):
|
def print_rules(rules):
|
||||||
|
print("// ---- Functions to parse a non-terminal according to a rule ----")
|
||||||
print_unit_rules(rules)
|
print_unit_rules(rules)
|
||||||
|
print("// ---- Functions to parse a non-terminal by testing all rules ----")
|
||||||
print_global_rules()
|
print_global_rules()
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,33 +88,36 @@ def print_unit_rules(rules):
|
||||||
left = rule[0]
|
left = rule[0]
|
||||||
rules_dict[left] += 1
|
rules_dict[left] += 1
|
||||||
code = get_code(left)
|
code = get_code(left)
|
||||||
print(f"""int parse_{code}{rules_dict[left]}(char* word, int pos) {{
|
print(f"""\
|
||||||
|
int parse_{code}{rules_dict[left]}(char* word, int pos) {{
|
||||||
int totalCharParsed = 0;
|
int totalCharParsed = 0;
|
||||||
int nbCharParsed = 0;
|
int nbCharParsed;
|
||||||
printf("Entering {code}{rules_dict[left]}\\n");
|
printf("Entering {code}{rules_dict[left]}\\n");""")
|
||||||
""")
|
|
||||||
for element in rule[1]:
|
for element in rule[1]:
|
||||||
elem_code = get_code(element)
|
elem_code = get_code(element)
|
||||||
if elem_code != "":
|
if elem_code != "":
|
||||||
print(f""" nbCharParsed = parse_{elem_code}(word, pos + totalCharParsed);
|
print(f"""
|
||||||
|
nbCharParsed = parse_{elem_code}(word, pos + totalCharParsed);
|
||||||
if (nbCharParsed == -1) {{
|
if (nbCharParsed == -1) {{
|
||||||
printf("Fail {elem_code} in {code}{rules_dict[left]}\\n");
|
printf("Fail {elem_code} in {code}{rules_dict[left]}\\n");
|
||||||
return -1;
|
return -1;
|
||||||
}}
|
}}
|
||||||
totalCharParsed += nbCharParsed;""")
|
totalCharParsed += nbCharParsed;""")
|
||||||
else:
|
else:
|
||||||
print(f" printf(\"Epsilon! -> Success\\n\");")
|
print(f"\n printf(\"Epsilon! -> Success\\n\");")
|
||||||
print(f"""
|
print(f"""
|
||||||
printf("Success {code}{rules_dict[left]}\\n");
|
printf("Success {code}{rules_dict[left]}\\n");
|
||||||
return totalCharParsed;
|
return totalCharParsed;
|
||||||
}}""")
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
def print_global_rules():
|
def print_global_rules():
|
||||||
for (key, value) in rules_dict.items():
|
for (key, value) in rules_dict.items():
|
||||||
code = get_code(key)
|
code = get_code(key)
|
||||||
print(f"""int parse_{code}(char* word, int pos) {{
|
print(f"""\
|
||||||
int nbCharParsed = 0;
|
int parse_{code}(char* word, int pos) {{
|
||||||
|
int nbCharParsed;
|
||||||
printf("Entering {key}\\n");""")
|
printf("Entering {key}\\n");""")
|
||||||
for i in range(1, value + 1):
|
for i in range(1, value + 1):
|
||||||
print(f"""
|
print(f"""
|
||||||
|
@ -124,7 +127,8 @@ def print_global_rules():
|
||||||
}}""")
|
}}""")
|
||||||
print("""
|
print("""
|
||||||
return -1;
|
return -1;
|
||||||
}""")
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
def get_code(s):
|
def get_code(s):
|
||||||
|
@ -133,19 +137,28 @@ def get_code(s):
|
||||||
|
|
||||||
def print_terminal_rules():
|
def print_terminal_rules():
|
||||||
for t in terminals_set:
|
for t in terminals_set:
|
||||||
|
# escape \ and " in the terminal
|
||||||
|
safeT = "\\" + t if (t == '"' or t == '\\') else t
|
||||||
|
|
||||||
code = get_code(t)
|
code = get_code(t)
|
||||||
l = len(t)
|
l = len(t)
|
||||||
print(f"""int parse_{code}(char* word, int pos) {{
|
print(f"""\
|
||||||
|
int parse_{code}(char* word, int pos) {{
|
||||||
|
// Extract the next {l} chars of the word
|
||||||
char substr[{l+1}];
|
char substr[{l+1}];
|
||||||
substr[0] = '\\0';
|
substr[0] = '\\0';
|
||||||
strncat(substr, &word[pos], {l});
|
strncat(substr, &word[pos], {l});
|
||||||
if (strcmp(substr, "{t}") == 0) {{
|
|
||||||
print_with_indent(pos, "{code}\\n");
|
// Compare this extracted string to the terminal,
|
||||||
return {l};
|
// and check if the next char is a space or the end of the string
|
||||||
|
if (strcmp(substr, "{safeT}") == 0 && (word[pos+{l}] == ' ' || word[pos+{l}] == '\\0')) {{
|
||||||
|
print_with_indent(pos, "{safeT}\\n");
|
||||||
|
return {l+1};
|
||||||
}} else {{
|
}} else {{
|
||||||
return -1;
|
return -1;
|
||||||
}}
|
}}
|
||||||
}}""")
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
S : a S b
|
||||||
S : int
|
S : int
|
||||||
S : string
|
S : " string "
|
||||||
S : { Assoc }
|
S : { Assoc }
|
||||||
Assoc : KeyVal AssocBis
|
Assoc : KeyVal AssocBis
|
||||||
Assoc :
|
Assoc :
|
||||||
|
|
Loading…
Reference in a new issue