2 #include "bc_read_stream.h"
3 #include "interpreter.h"
14 #define BC_INTFA_STATE 0
15 #define BC_INTFA_FINAL_STATE 1
16 #define BC_INTFA_TRANSITION 2
17 #define BC_INTFA_TRANSITION_RANGE 3
22 #define BC_RTN_STATE 1
23 #define BC_RTN_TRANSITION_TERMINAL 2
24 #define BC_RTN_TRANSITION_NONTERM 3
25 #define BC_RTN_DECISION 4
26 #define BC_RTN_IGNORE 5
28 void check_error(struct bc_read_stream
*s
)
30 if(bc_rs_get_error(s
))
32 int err
= bc_rs_get_error(s
);
33 printf("There were stream errors!\n");
34 if(err
& BITCODE_ERR_VALUE_TOO_LARGE
)
35 printf(" Value too large.\n");
36 if(err
& BITCODE_ERR_NO_SUCH_VALUE
)
37 printf(" No such value.\n");
38 if(err
& BITCODE_ERR_IO
)
39 printf(" IO error.\n");
40 if(err
& BITCODE_ERR_CORRUPT_INPUT
)
41 printf(" Corrupt input.\n");
42 if(err
& BITCODE_ERR_INTERNAL
)
43 printf(" Internal error.\n");
47 void unexpected(struct bc_read_stream
*s
, struct record_info ri
)
49 printf("Unexpected. Record is: ");
50 if(ri
.record_type
== DataRecord
)
52 printf("data, id=%d, %d records\n", ri
.id
, bc_rs_get_record_size(s
));
54 else if(ri
.record_type
== StartBlock
)
56 printf("start block, id=%d\n", ri
.id
);
58 else if(ri
.record_type
== EndBlock
)
60 printf("end block\n");
62 else if(ri
.record_type
== Eof
)
66 else if(ri
.record_type
== Err
)
72 char **load_strings(struct bc_read_stream
*s
)
74 /* first get a count of the strings */
79 struct record_info ri
= bc_rs_next_data_record(s
);
80 if(ri
.record_type
== DataRecord
)
82 else if(ri
.record_type
== EndBlock
)
88 bc_rs_rewind_block(s
);
89 char **strings
= malloc((num_strings
+1) * sizeof(*strings
));
90 int string_offset
= 0;
94 struct record_info ri
= bc_rs_next_data_record(s
);
95 if(ri
.record_type
== DataRecord
&& ri
.id
== BC_STRING
)
97 char *str
= malloc((bc_rs_get_record_size(s
)+1) * sizeof(char));
99 for(i
= 0; bc_rs_get_remaining_record_size(s
) > 0; i
++)
101 str
[i
] = bc_rs_read_next_32(s
);
106 strings
[string_offset
++] = str
;
108 else if(ri
.record_type
== EndBlock
)
116 strings
[string_offset
] = NULL
;
120 void load_intfa(struct bc_read_stream
*s
, struct intfa
*intfa
, char **strings
)
122 /* first get a count of the states and transitions */
123 intfa
->num_states
= 0;
124 intfa
->num_transitions
= 0;
128 struct record_info ri
= bc_rs_next_data_record(s
);
129 if(ri
.record_type
== DataRecord
)
131 if(ri
.id
== BC_INTFA_STATE
|| ri
.id
== BC_INTFA_FINAL_STATE
)
133 else if(ri
.id
== BC_INTFA_TRANSITION
|| ri
.id
== BC_INTFA_TRANSITION_RANGE
)
134 intfa
->num_transitions
++;
136 else if(ri
.record_type
== EndBlock
)
142 bc_rs_rewind_block(s
);
143 intfa
->states
= malloc(intfa
->num_states
* sizeof(*intfa
->states
));
144 intfa
->transitions
= malloc(intfa
->num_transitions
* sizeof(*intfa
->transitions
));
145 int state_offset
= 0;
146 int transition_offset
= 0;
147 int state_transition_offset
= 0;
151 struct record_info ri
= bc_rs_next_data_record(s
);
152 if(ri
.record_type
== DataRecord
)
154 if(ri
.id
== BC_INTFA_STATE
|| ri
.id
== BC_INTFA_FINAL_STATE
)
156 struct intfa_state
*state
= &intfa
->states
[state_offset
++];
158 state
->num_transitions
= bc_rs_read_next_32(s
);
159 state
->transitions
= &intfa
->transitions
[state_transition_offset
];
160 state_transition_offset
+= state
->num_transitions
;
162 if(ri
.id
== BC_INTFA_FINAL_STATE
)
163 state
->final
= strings
[bc_rs_read_next_32(s
)];
167 else if(ri
.id
== BC_INTFA_TRANSITION
|| ri
.id
== BC_INTFA_TRANSITION_RANGE
)
169 struct intfa_transition
*transition
= &intfa
->transitions
[transition_offset
++];
171 if(ri
.id
== BC_INTFA_TRANSITION
)
173 transition
->ch_low
= transition
->ch_high
= bc_rs_read_next_8(s
);
175 else if(ri
.id
== BC_INTFA_TRANSITION_RANGE
)
177 transition
->ch_low
= bc_rs_read_next_8(s
);
178 transition
->ch_high
= bc_rs_read_next_8(s
);
181 transition
->dest_state
= &intfa
->states
[bc_rs_read_next_8(s
)];
184 else if(ri
.record_type
== EndBlock
)
191 void load_intfas(struct bc_read_stream
*s
, struct grammar
*g
)
193 /* first get a count of the intfas */
197 struct record_info ri
= bc_rs_next_data_record(s
);
198 if(ri
.record_type
== StartBlock
&& ri
.id
== BC_INTFA
)
203 else if(ri
.record_type
== EndBlock
)
209 bc_rs_rewind_block(s
);
210 g
->intfas
= malloc((g
->num_intfas
) * sizeof(*g
->intfas
));
211 int intfa_offset
= 0;
215 struct record_info ri
= bc_rs_next_data_record(s
);
216 if(ri
.record_type
== StartBlock
&& ri
.id
== BC_INTFA
)
218 load_intfa(s
, &g
->intfas
[intfa_offset
++], g
->strings
);
220 else if(ri
.record_type
== EndBlock
)
227 void load_rtn(struct bc_read_stream
*s
, struct rtn
*rtn
, struct grammar
*g
)
229 /* first get a count of the ignores, states, and transitions */
232 rtn
->num_transitions
= 0;
236 struct record_info ri
= bc_rs_next_data_record(s
);
237 if(ri
.record_type
== DataRecord
)
239 if(ri
.id
== BC_RTN_IGNORE
)
241 else if(ri
.id
== BC_RTN_STATE
)
243 else if(ri
.id
== BC_RTN_TRANSITION_TERMINAL
||
244 ri
.id
== BC_RTN_TRANSITION_NONTERM
||
245 ri
.id
== BC_RTN_DECISION
)
246 rtn
->num_transitions
++;
248 else if(ri
.record_type
== EndBlock
)
254 bc_rs_rewind_block(s
);
255 rtn
->ignore_terminals
= malloc(rtn
->num_ignore
* sizeof(*rtn
->ignore_terminals
));
256 rtn
->states
= malloc(rtn
->num_states
* sizeof(*rtn
->states
));
257 rtn
->transitions
= malloc(rtn
->num_transitions
* sizeof(*rtn
->transitions
));
259 int ignore_offset
= 0;
260 int state_offset
= 0;
261 int transition_offset
= 0;
262 int state_transition_offset
= 0;
266 struct record_info ri
= bc_rs_next_data_record(s
);
267 if(ri
.record_type
== DataRecord
)
269 if(ri
.id
== BC_RTN_INFO
)
271 rtn
->name
= g
->strings
[bc_rs_read_next_32(s
)];
272 rtn
->num_slots
= bc_rs_read_next_32(s
);
274 else if(ri
.id
== BC_RTN_IGNORE
)
276 rtn
->ignore_terminals
[ignore_offset
++] = g
->strings
[bc_rs_read_next_32(s
)];
278 else if(ri
.id
== BC_RTN_STATE
)
280 struct rtn_state
*state
= &rtn
->states
[state_offset
++];
282 state
->num_transitions
= bc_rs_read_next_32(s
);
283 state
->transitions
= &rtn
->transitions
[state_transition_offset
];
284 state_transition_offset
+= state
->num_transitions
;
286 state
->term_dfa
= &g
->intfas
[bc_rs_read_next_32(s
)];
288 if(bc_rs_read_next_8(s
))
289 state
->is_final
= true;
291 state
->is_final
= false;
293 else if(ri
.id
== BC_RTN_TRANSITION_TERMINAL
||
294 ri
.id
== BC_RTN_TRANSITION_NONTERM
||
295 ri
.id
== BC_RTN_DECISION
)
297 struct rtn_transition
*transition
= &rtn
->transitions
[transition_offset
++];
299 if(ri
.id
== BC_RTN_TRANSITION_TERMINAL
|| ri
.id
== BC_RTN_TRANSITION_NONTERM
)
301 if(ri
.id
== BC_RTN_TRANSITION_TERMINAL
)
303 transition
->transition_type
= TERMINAL_TRANSITION
;
304 transition
->edge
.terminal_name
= g
->strings
[bc_rs_read_next_32(s
)];
306 else if(ri
.id
== BC_RTN_TRANSITION_NONTERM
)
308 transition
->transition_type
= NONTERM_TRANSITION
;
309 transition
->edge
.nonterminal
= &g
->rtns
[bc_rs_read_next_32(s
)];
312 transition
->dest_state
= &rtn
->states
[bc_rs_read_next_32(s
)];
313 transition
->slotname
= g
->strings
[bc_rs_read_next_32(s
)];
314 transition
->slotnum
= bc_rs_read_next_32(s
);
316 else if(ri
.id
== BC_RTN_DECISION
)
318 transition
->transition_type
= DECISION
;
319 char *terminal_name
= g
->strings
[bc_rs_read_next_32(s
)];
321 transition
->edge
.decision
= malloc(sizeof(struct decision
) +
322 (sizeof(struct rtn_transition
) * bc_rs_get_remaining_record_size(s
)));
324 struct decision
*d
= transition
->edge
.decision
;
325 d
->terminal_name
= terminal_name
;
326 d
->num_actions
= bc_rs_get_remaining_record_size(s
);
328 for(int action_num
= 0; bc_rs_get_remaining_record_size(s
) > 0; action_num
++)
330 d
->actions
[action_num
] = bc_rs_read_next_32(s
);
335 else if(ri
.record_type
== EndBlock
)
342 void load_rtns(struct bc_read_stream
*s
, struct grammar
*g
)
344 /* first get a count of the rtns */
348 struct record_info ri
= bc_rs_next_data_record(s
);
349 if(ri
.record_type
== StartBlock
&& ri
.id
== BC_RTN
)
354 else if(ri
.record_type
== EndBlock
)
360 bc_rs_rewind_block(s
);
361 g
->rtns
= malloc(g
->num_rtns
* sizeof(*g
->rtns
));
366 struct record_info ri
= bc_rs_next_data_record(s
);
367 if(ri
.record_type
== StartBlock
&& ri
.id
== BC_RTN
)
369 load_rtn(s
, &g
->rtns
[rtn_offset
++], g
);
371 else if(ri
.record_type
== EndBlock
)
378 struct grammar
*load_grammar(struct bc_read_stream
*s
)
380 struct grammar
*g
= malloc(sizeof(*g
));
384 struct record_info ri
= bc_rs_next_data_record(s
);
385 if(ri
.record_type
== StartBlock
)
387 if(ri
.id
== BC_STRINGS
)
388 g
->strings
= load_strings(s
);
389 else if(ri
.id
== BC_INTFAS
)
391 else if(ri
.id
== BC_RTNS
)
396 else if(ri
.record_type
== Eof
)
398 if(g
->strings
== NULL
|| g
->num_intfas
== 0 || g
->num_rtns
== 0)
400 printf("Premature EOF!\n");
405 /* Success -- we finished loading! */
414 void free_grammar(struct grammar
*g
)
416 for(int i
= 0; g
->strings
[i
] != NULL
; i
++)
420 for(int i
= 0; i
< g
->num_rtns
; i
++)
422 struct rtn
*rtn
= &g
->rtns
[i
];
423 free(rtn
->ignore_terminals
);
426 for(int j
= 0; j
< rtn
->num_transitions
; j
++)
427 if(rtn
->transitions
[j
].transition_type
== DECISION
)
428 free(rtn
->transitions
[j
].edge
.decision
);
429 free(rtn
->transitions
);
433 for(int i
= 0; i
< g
->num_intfas
; i
++)
435 struct intfa
*intfa
= &g
->intfas
[i
];
437 free(intfa
->transitions
);
446 * c-file-style: "bsd"
448 * indent-tabs-mode: nil