summaryrefslogtreecommitdiff
path: root/src/reader.c
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2022-01-04 20:24:07 +0800
committerJSDurand <mmemmew@gmail.com>2022-01-04 20:24:07 +0800
commit949888ad5d0cd0f9f9a87f9938a632b3e32df051 (patch)
treeae9155484a3a5b4124c6d3fae14ada9d718c8579 /src/reader.c
parent55dc897da6e81f2a26cfc7e66ac942824773498b (diff)
Fix problems
Now some problems are fixed. It can now read grammar correctly (hopefully) from a file, in the BNF format. And strings (terminals) are handled fine as well. So glad that there are no leak problems now.
Diffstat (limited to 'src/reader.c')
-rw-r--r--src/reader.c154
1 files changed, 113 insertions, 41 deletions
diff --git a/src/reader.c b/src/reader.c
index 1e7c49c..18435a9 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -21,12 +21,12 @@
/* Read a string of TNT's into TNTS. TNTS is expected to be already
allocated. */
-static void
+static unsigned char
read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
{
str_info info;
- /* fleprintf("%s:%d, S = %lu, E = %lu\n", start, end); */
+ /* fleprintf("S = %lu, E = %lu\n", start, end); */
unsigned char readingp = 0, stop = 0;
@@ -42,7 +42,7 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
case 10:
case 13:
/* if a newline is somehow encountered, we stop reading */
- fleprintf0("%s:%d, hi\n");
+ /* fleprintf0("hi\n"); */
stop = 1;
break;
case 9:
@@ -56,12 +56,12 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
nt_index = find_in_cpa_list(string, string_size, cpa_list);
if (nt_index < 0) {
- fleprintf("%s:%d:%lu, Undefined non-terminal: ", index);
+ fleprintf("index = %lu, Undefined non-terminal: ", index);
print_name(&((cpa) { string, string_size }));
printf("\n");
free(string);
string = NULL;
- return;
+ return 1;
}
free(string);
@@ -83,6 +83,7 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
strinfo.value != 39 &&
strinfo.value != 10 &&
strinfo.value != 13;) {
+ strinfo = get_info(s, strindex);
if (strinfo.value == 92) {
strindex += info.step;
@@ -93,26 +94,32 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
paranoid. */
if (strindex >= end) {
local_exit = 1;
- fleprintf("%s:%d:%lu, Escape end\n", strindex);
+ fleprintf("strindex = %lu, Escape end\n", strindex);
}
strinfo = get_info(s, strindex);
if (strinfo.value == 10 || strinfo.value == 13) {
local_exit = 1;
- fleprintf("%s:%d:%lu, Escape newline not allowed\n",
+ fleprintf("strindex = %lu, Escape newline not allowed\n",
strindex);
}
/* cleanup */
/* no cleanup needed */
- if (local_exit) return;
+ if (local_exit) return 1;
}
*(tnts+tnt_count++) = (TNT) { 0, { .t = strinfo.value } };
strindex += strinfo.step;
}
+
+ strindex -= strinfo.step;
+ tnt_count--;
+
+ index = strindex;
+ info = get_info(s, index);
break;
default:
if (!readingp) {
@@ -123,26 +130,26 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
/* if we are at the end, we need to process one additional
non-terminal */
if (index < end && index + (NUM) info.step >= end) {
- /* fleprintf0("%s:%d, hello\n"); */
+ /* fleprintf0("hello\n"); */
COUNT_CPA(last_index, index+(NUM) info.step,
s, string_size);
- /* fleprintf0("%s:%d, hello\n"); */
+ /* fleprintf0("hello\n"); */
string = MYALLOC(NUM, string_size+1);
READ_CPA(string, last_index, index+(NUM) info.step,
s, string_size);
- /* fleprintf0("%s:%d, hello\n"); */
+ /* fleprintf0("hello\n"); */
nt_index = find_in_cpa_list(string, string_size, cpa_list);
- /* fleprintf0("%s:%d, hello\n"); */
+ /* fleprintf0("hello\n"); */
if (nt_index < 0) {
- fleprintf("%s:%d:%lu, Undefined non-terminal: ", index);
+ fleprintf("index = %lu, Undefined non-terminal: ", index);
print_name(&((cpa) { string, string_size }));
printf("\n");
eprintf("END = %lu\n", end);
free(string);
string = NULL;
- return;
+ return 1;
}
free(string);
@@ -155,6 +162,8 @@ read_tnt_string(str *s, NUM start, NUM end, TNT *tnts, List *cpa_list)
index += info.step;
}
+
+ return 0;
}
static void
@@ -169,7 +178,7 @@ read_grammar_from_bnf(str *s)
{
NUM len = str_length(s);
- /* fleprintf("%s:%d, len = %lu\n", len); */
+ /* fleprintf("len = %lu\n", len); */
/* The first loop collects names of non-terminals */
@@ -197,7 +206,7 @@ read_grammar_from_bnf(str *s)
readingp = 0;
if (definitionp) {
- fleprintf("%s:%d:%lu, A non-terminal cannot have spaces in "
+ fleprintf("%lu, A non-terminal cannot have spaces in "
"the name\n", index);
/* cleanup */
map_list(names, destroy_cpa_and_free_all);
@@ -233,14 +242,14 @@ read_grammar_from_bnf(str *s)
}
add_to_list(line_indices, line_index);
- /* fleprintf0("%s:%d, Definition should be over\n"); */
+ /* fleprintf0("Definition should be over\n"); */
}
break;
default:
if (!readingp) {
last_index = index;
readingp = 1;
- /* fleprintf0("%s:%d, Start reading\n"); */
+ /* fleprintf0("Start reading\n"); */
}
break;
}
@@ -268,7 +277,7 @@ read_grammar_from_bnf(str *s)
/* last index is used to collect strings */
for (NUM index = 0, last_index = 0; index < len;) {
str_info info = get_info(s, index);
- /* fleprintf("%s:%d, index = %lu, value = %lu\n", index, info.value); */
+ /* fleprintf("index = %lu, value = %lu\n", index, info.value); */
TNT *current_tnt_string = NULL;
@@ -279,7 +288,7 @@ read_grammar_from_bnf(str *s)
case 34: /* double quote */
case 39: /* single quote */
if (definitionp) {
- fleprintf("%s:%d:%lu, A non-terminal cannot have quotes in "
+ fleprintf("%lu, A non-terminal cannot have quotes in "
"the name\n", index);
/* cleanup */
map_list(names, destroy_cpa_and_free_all);
@@ -293,9 +302,31 @@ read_grammar_from_bnf(str *s)
} else {
/* read a string of terminals */
+ if (readingp) {
+ fleprintf("Name of non-terminal should not contain quotes, "
+ "index = %lu\n", index);
+ /* cleanup */
+ map_list(names, destroy_cpa_and_free_all);
+ destroy_list(names, 0);
+
+ destroy_list(line_indices, 1);
+
+ map_list(rules, destroy_rule_and_free_first);
+ destroy_list(rules, 0);
+ return NULL;
+ }
+
+ if (!readingp && !right_start_p) {
+ last_index = index;
+ right_start_p = 1;
+ }
+
NUM strindex = index + info.step;
str_info strinfo = get_info(s, strindex);
+ /* fleprintf("start reading string at %lu, value = %lu\n",
+ * strindex, strinfo.value); */
+
for (;strindex < len &&
strinfo.value != 13 &&
strinfo.value != 10 &&
@@ -312,11 +343,11 @@ read_grammar_from_bnf(str *s)
if (strindex >= len) {
local_error_p = 1;
- fleprintf("%s:%d:%ld, Escape at the end not allowed\n",
+ fleprintf("%ld, Escape at the end not allowed\n",
strindex);
} else if (strinfo.value == 13 || strinfo.value == 10) {
local_error_p = 1;
- fleprintf("%s:%d:%ld, Escape newline in string not "
+ fleprintf("%ld, Escape newline in string not "
"allowed\n", strindex);
}
@@ -336,23 +367,49 @@ read_grammar_from_bnf(str *s)
tnt_count++;
strindex += strinfo.step;
+ /* fleprintf("now strindex = %lu, value = %lu\n",
+ * strindex, strinfo.value); */
}
- if (strinfo.value == 13 || strinfo.value == 10) {
- fleprintf("%s:%d:%ld, Newline encountered before string "
- "ended\n", strindex);
- /* cleanup */
- map_list(names, destroy_cpa_and_free_all);
- destroy_list(names, 0);
+ if (strindex < len) {
+ strindex -= strinfo.step;
+ tnt_count--;
- destroy_list(line_indices, 1);
+ index = strindex;
- map_list(rules, destroy_rule_and_free_first);
- destroy_list(rules, 0);
- return NULL;
- }
+ info = get_info(s, index);
+ /* fleprintf("after reading a string, index = %lu, value = %lu\n",
+ * index, info.value); */
+
+ if (strinfo.value == 13 || strinfo.value == 10) {
+ fleprintf("%ld, Newline encountered before string "
+ "ended\n", strindex);
+ /* cleanup */
+ map_list(names, destroy_cpa_and_free_all);
+ destroy_list(names, 0);
+
+ destroy_list(line_indices, 1);
- index = strindex + 1;
+ map_list(rules, destroy_rule_and_free_first);
+ destroy_list(rules, 0);
+ return NULL;
+ }
+ } else {
+ if (strinfo.value != 34 &&
+ strinfo.value != 39) {
+ fleprintf0("input ended before string is left\n");
+ /* cleanup */
+ map_list(names, destroy_cpa_and_free_all);
+ destroy_list(names, 0);
+
+ destroy_list(line_indices, 1);
+
+ map_list(rules, destroy_rule_and_free_first);
+ destroy_list(rules, 0);
+ return NULL;
+ }
+
+ }
}
break;
@@ -360,7 +417,7 @@ read_grammar_from_bnf(str *s)
case ' ':
case 9:
if (definitionp) {
- fleprintf("%s:%d:%lu, A non-terminal cannot have spaces or "
+ fleprintf("%lu, A non-terminal cannot have spaces or "
"tabs in the name\n", index);
/* cleanup */
map_list(names, destroy_cpa_and_free_all);
@@ -382,19 +439,34 @@ read_grammar_from_bnf(str *s)
readingp = 0;
line_count++;
- /* fleprintf("%s:%d, tnt count = %lu\n", tnt_count); */
+ /* fleprintf("tnt count = %lu\n", tnt_count);
+ * fleprintf("right = %u\n", right_start_p); */
if (right_start_p) {
right_start_p = 0;
current_tnt_string = new_tnt_pointer(tnt_count);
- read_tnt_string(s, last_index, index, current_tnt_string,
- names);
+ if (read_tnt_string
+ (s, last_index, index, current_tnt_string,
+ names)) {
+ /* something went wrong in readnig TNT string */
+ /* cleanup */
+ map_list(names, destroy_cpa_and_free_all);
+ destroy_list(names, 0);
+
+ destroy_list(line_indices, 1);
+
+ map_list(rules, destroy_rule_and_free_first);
+ destroy_list(rules, 0);
+ return NULL;
+ }
printf("%s:%d:%lu, Printing a TNT string: ",
__FILE__, __LINE__, index);
- for (int i = 0; i < (int) tnt_count;)
+ for (int i = 0; i < (int) tnt_count;) {
print_tnt(current_tnt_string+i++);
+ if (i<tnt_count) printf(", ");
+ }
printf("\n");
temp_pointers = MYALLOC(void *, tnt_count);
@@ -420,7 +492,7 @@ read_grammar_from_bnf(str *s)
right_start_p = 0;
/* the non-terminal at this line is cached by line_indices */
current_nt = *((NUM *) list_nth(line_indices, line_count));
- /* fleprintf("%s:%d, current nt = %u, count = %lu\n",
+ /* fleprintf("current nt = %u, count = %lu\n",
* current_nt, line_count); */
break;
default:
@@ -447,7 +519,7 @@ read_grammar_from_bnf(str *s)
Grammar *g = new_grammar();
if (build_grammar(g, rules, names)) {
- fleprintf0("%s:%d, Failed to build the grammar\n");
+ fleprintf0("Failed to build the grammar\n");
map_list(names, destroy_cpa_and_free_all);
destroy_list(names, 0);
map_list(rules, destroy_rule_and_free_first);