First draft
This commit is contained in:
parent
62894d15db
commit
729cbf9a50
2 changed files with 142 additions and 10 deletions
140
main.py
140
main.py
|
@ -1,16 +1,144 @@
|
||||||
|
|
||||||
|
rules_dict = {}
|
||||||
|
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]
|
||||||
rules = [(line[0], line[1].strip().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_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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
def print_rules(rules):
|
||||||
for rule in rules:
|
print_unit_rules(rules)
|
||||||
print("void parse_%s(...) {" % rule[0])
|
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]:
|
for element in rule[1]:
|
||||||
print(" parse_%s(...);" % element)
|
elem_code = get_code(element)
|
||||||
print("}")
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|
12
sample.txt
12
sample.txt
|
@ -1,4 +1,8 @@
|
||||||
T -> S u S
|
S : int
|
||||||
T -> x S y
|
S : string
|
||||||
S -> a S b
|
S : { Assoc }
|
||||||
S ->
|
Assoc : KeyVal AssocBis
|
||||||
|
Assoc :
|
||||||
|
AssocBis : , KeyVal AssocBis
|
||||||
|
AssocBis :
|
||||||
|
KeyVal : id = S
|
||||||
|
|
Loading…
Reference in a new issue