-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathtest_parser.c
More file actions
187 lines (167 loc) · 6.89 KB
/
test_parser.c
File metadata and controls
187 lines (167 loc) · 6.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
Copyright 2002-2006 John Plevyak, All Rights Reserved
*/
#include "d.h"
#include "mkdparse.h"
#define SIZEOF_MY_PARSE_NODE 100 /* permit test cases up to this size */
static int save_parse_tree = 1;
static int partial_parses = 0;
static int fixup = 1;
static int fixup_ebnf = 0;
static int compare_stacks = 1;
static int no_height_disamb = 0;
static int no_greedy_disamb = 0;
static int commit_actions_interval = 100;
static int start_state = 0;
static char start_state_name[256];
static int set_op_priority_from_rule = 0;
static int right_recursive_BNF = 0;
static int states_for_whitespace = 1;
static int states_for_all_nterms = 0;
static int tokenizer = 0;
static int longest_match = 0;
static int scanner_blocks = 4;
static int scanner_block_size;
static void help(ArgumentState *arg_state, char *arg_unused);
ArgumentDescription arg_desc[] = {
{"longest_match", 'l', "Use Longest Match Rule for Tokens", "T", &longest_match, "D_MAKE_LONGEST_MATCH", NULL},
{"tokenizer", 'T', "Tokenizer for START", "T", &tokenizer, "D_MAKE_PARSER_TOKENIZER", NULL},
{"whitespace_states", 'C', "Compute Whitespace States", "T", &states_for_whitespace, "D_MAKE_PARSER_WHITESPACE",
NULL},
{"all_states", 'A', "Compute States For All NTERMs", "T", &states_for_all_nterms, "D_MAKE_PARSER_ALL_NTERMS", NULL},
{"scanner_blocks", 'b', "Scanner Blocks", "I", &scanner_blocks, "D_MAKE_PARSER_SCANNER_BLOCKS", NULL},
{"op_pri_from_rule", 'p', "Set Operator Priority From Rule", "T", &set_op_priority_from_rule,
"D_MAKE_PARSER_SET_PRIORITY", NULL},
{"right_recurse_BNF", 'r', "Use Right Recursion For */+", "T", &right_recursive_BNF,
"D_MAKE_PARSER_RIGHT_RECURSIVE_BNF", NULL},
{"start_state", 'S', "Start State", "I", &start_state, "D_PARSE_START_STATE", NULL},
{"start_state_name", 'N', "Start State Name", "S256", &start_state_name, "D_PARSE_START_STATE_NAME", NULL},
{"save_parse_tree", 's', "Save Parse Tree", "T", &save_parse_tree, "D_PARSE_SAVE_PARSE_TREE", NULL},
{"partial_parses", 'p', "Partial Parses", "T", &partial_parses, "D_PARSE_PARTIAL_PARSES", NULL},
{"compare_stacks", 'c', "Compare Stacks", "T", &compare_stacks, "D_PARSE_COMPARE_STACKS", NULL},
{"commit_interval", 'i', "Commit Interval", "I", &commit_actions_interval, "D_PARSE_COMMIT_INTERVAL", NULL},
{"fixup", 'f', "Fixup Internal Productions", "T", &fixup, "D_PARSE_FIXUP", NULL},
{"fixup_ebnf", 'e', "Fixup EBNF Productions", "T", &fixup_ebnf, "D_PARSE_FIXUP_EBNF", NULL},
{"noheight", 'H', "Do not use Height Disambiguization", "T", &no_height_disamb, "D_PARSE_NO_HEIGHT_DISAMB", NULL},
{"nogreedy", 'G', "Do not use Greedy Disambiguization", "T", &no_greedy_disamb, "D_PARSE_NO_GREEDY_DISAMB", NULL},
{"verbose", 'v', "Verbose", "+", &d_verbose_level, "D_PARSE_VERBOSE", NULL},
{"test", 't', "Test", "+", &test_level, "D_PARSE_TEST", NULL},
{"debug", 'd', "Debug", "+", &d_debug_level, "D_PARSE_DEBUG", NULL},
{"help", 'h', "Help", NULL, NULL, NULL, help},
{0}};
ArgumentState arg_state = {0, 0, "program", arg_desc};
static void help(ArgumentState *arg_state, char *arg_unused) {
char ver[60];
d_version(ver);
fprintf(stderr, "Test DParser Version %s ", ver);
fprintf(stderr, "Copyright (c) 2002-2013 John Plevyak\n");
usage(arg_state, arg_unused);
}
char *ops = "+";
void *ops_cache = NULL;
int ops_scan(char *ops, void *ops_cache, d_loc_t *loc, unsigned char *op_assoc, int *op_priority) {
(void)ops;
(void)ops_cache;
if (loc->s[0] == '+') {
loc->s++;
*op_assoc = ASSOC_BINARY_LEFT;
*op_priority = 9500;
return 1;
}
return 0;
}
int spec_code(void *new_ps, void **children, int n_children, int pn_offset, struct D_Parser *parser) {
(void)new_ps;
(void)children;
(void)n_children;
(void)pn_offset;
(void)parser;
return 0;
}
int final_code(void *new_ps, void **children, int n_children, int pn_offset, struct D_Parser *parser) {
(void)new_ps;
(void)children;
(void)n_children;
(void)pn_offset;
(void)parser;
return 0;
}
int d_get_start_state(D_ParserTables* parser_tables_gram, char *name) {
int i;
for (i = 0; i < parser_tables_gram->nsymbols; i++)
if (parser_tables_gram->symbols[i].kind == D_SYMBOL_NTERM && !strcmp(parser_tables_gram->symbols[i].name, name))
return parser_tables_gram->symbols[i].start_symbol;
return -1;
}
int main(int argc, char *argv[]) {
int i, len = 0;
char *buf = NULL, *fn, *grammar_pathname;
D_Parser *p;
D_ParseNode *pn = NULL;
unsigned char *str = NULL;
unsigned int str_len;
Grammar *g;
BinaryTables *binary_tables;
(void)argc;
process_args(&arg_state, argv);
if (arg_state.nfile_arguments < 2) help(&arg_state, NULL);
/* build grammar */
grammar_pathname = arg_state.file_argument[0];
g = new_D_Grammar(grammar_pathname);
g->set_op_priority_from_rule = set_op_priority_from_rule;
g->right_recursive_BNF = right_recursive_BNF;
g->states_for_whitespace = states_for_whitespace;
g->states_for_all_nterms = states_for_all_nterms;
g->tokenizer = tokenizer;
g->longest_match = longest_match;
g->scanner_blocks = scanner_blocks;
g->scanner_block_size = scanner_block_size;
if (!(str = (unsigned char *)sbuf_read(grammar_pathname)))
d_fail("unable to read grammar file '%s'", grammar_pathname);
mkdparse_from_string(g, (char *)str);
d_free(str);
str = 0;
if (write_binary_tables_to_string(g, &str, &str_len) < 0)
d_fail("unable to write tables to string '%s'", grammar_pathname);
free_D_Grammar(g);
/* execute parser */
binary_tables = read_binary_tables_from_string(str, spec_code, final_code);
d_free(str);
p = new_D_Parser(binary_tables->parser_tables_gram, SIZEOF_MY_PARSE_NODE);
p->save_parse_tree = save_parse_tree;
p->ambiguity_fn = ambiguity_count_fn;
p->partial_parses = partial_parses;
p->dont_fixup_internal_productions = !fixup;
p->fixup_EBNF_productions = fixup_ebnf;
p->dont_compare_stacks = !compare_stacks;
p->dont_use_height_for_disambiguation = no_height_disamb;
p->dont_use_greediness_for_disambiguation = no_greedy_disamb;
p->commit_actions_interval = commit_actions_interval;
p->start_state = start_state;
if (start_state_name[0])
p->start_state = d_get_start_state(binary_tables->parser_tables_gram, start_state_name);
if (p->start_state < 0)
d_fail("unknown start state '%s'", start_state_name);
for (i = 1; i < arg_state.nfile_arguments; i++) {
p->loc.pathname = arg_state.file_argument[i];
p->loc.line = 1;
p->loc.col = 0;
if (buf_read(arg_state.file_argument[i], &buf, &len) > 0)
pn = dparse(p, buf, len);
else
d_fail("unable to read file '%s'", arg_state.file_argument[i]);
if (pn) {
free_D_ParseNode(p, pn);
pn = 0;
} else {
fn = d_dup_pathname_str(p->loc.pathname);
fprintf(stderr, "fatal error, '%s' line %d\n", fn, p->loc.line);
FREE(fn);
}
if (buf) FREE(buf);
}
free_BinaryTables(binary_tables);
free_D_Parser(p);
free_args(&arg_state);
exit(0);
}