4 #include "interpreter.h"
6 struct parse_stack_frame
*init_new_stack_frame(struct parse_state
*parse_state
, struct rtn
*rtn
)
8 struct parse_stack_frame
*frame
= &parse_state
->parse_stack
[parse_state
->parse_stack_length
++];
10 frame
->rtn_state
= &rtn
->states
[0];
11 frame
->slots
.rtn
= rtn
;
12 frame
->slots
.num_slots
= rtn
->num_slots
;
13 frame
->slots
.slots
= malloc(sizeof(struct parse_val
)*frame
->slots
.num_slots
);
17 struct parse_stack_frame
*pop_stack_frame(struct parse_state
*parse_state
)
19 struct parse_stack_frame
*frame
= &parse_state
->parse_stack
[parse_state
->parse_stack_length
-1];
20 free(frame
->slots
.slots
);
21 parse_state
->parse_stack_length
--;
22 if(parse_state
->parse_stack_length
== 0)
24 return NULL
; /* the parse is over */
29 frame
->rtn_state
= frame
->rtn_transition
->dest_state
;
34 void reset_dfa_match(struct parse_state
*parse_state
)
36 struct parse_stack_frame
*frame
= &parse_state
->parse_stack
[parse_state
->parse_stack_length
-1];
37 parse_state
->dfa
= frame
->rtn_state
->term_dfa
;
38 parse_state
->dfa_state
= &parse_state
->dfa
->states
[0];
39 parse_state
->match_begin
= parse_state
->offset
;
40 parse_state
->last_match_state
= NULL
;
43 void do_rtn_transition(struct parse_state
*parse_state
, int match_begin
, int match_len
, char *terminal
)
45 struct parse_stack_frame
*frame
= &parse_state
->parse_stack
[parse_state
->parse_stack_length
-1];
46 struct parse_val val
= {PARSE_VAL_TERMINAL
, {.terminal
= {match_begin
, match_len
}}};
47 bool found_transition
= false;
49 /* is this an ignored terminal? if so, just skip it */
50 for(int i
= 0; i
< frame
->rtn
->num_ignore
; i
++)
52 if(frame
->rtn
->ignore_terminals
[i
] == terminal
)
54 reset_dfa_match(parse_state
);
59 /* find a transition out of this RTN state on this terminal */
60 for(int i
= 0; i
< frame
->rtn_state
->num_transitions
; i
++)
62 struct rtn_transition
*t
= &frame
->rtn_state
->transitions
[i
];
63 if(t
->transition_type
== TERMINAL_TRANSITION
&& t
->edge
.terminal_name
== terminal
)
65 frame
->slots
.slots
[t
->slotnum
] = val
;
66 frame
->rtn_state
= t
->dest_state
;
67 found_transition
= true;
70 else if(t
->transition_type
== DECISION
&& t
->edge
.decision
->terminal_name
== terminal
)
72 struct decision
*d
= t
->edge
.decision
;
74 for(int i
= 0; i
< d
->num_actions
; i
++)
76 struct rtn_transition
*t2
= &frame
->rtn_state
->transitions
[d
->actions
[i
]];
78 if(t2
->transition_type
== NONTERM_TRANSITION
)
80 if(parse_state
->parse_stack_length
== parse_state
->parse_stack_size
)
82 printf("Need to reallocate parse stack!!\n");
85 frame
->rtn_transition
= t2
;
86 frame
= init_new_stack_frame(parse_state
, t2
->edge
.nonterminal
);
88 else if(t2
->transition_type
== TERMINAL_TRANSITION
)
90 frame
->slots
.slots
[t2
->slotnum
] = val
;
91 frame
->rtn_state
= t2
->dest_state
;
94 found_transition
= true;
101 while(parse_state
->parse_stack_length
> 0 && frame
->rtn_state
->is_final
)
102 frame
= pop_stack_frame(parse_state
);
104 if(parse_state
->parse_stack_length
> 0)
105 reset_dfa_match(parse_state
);
109 printf("Syntax error -- no RTN transition!!\n");
114 void parse(struct parse_state
*parse_state
)
116 bool user_cancelled
= false;
118 while(!parse_state
->buffer
->is_eof
&& !user_cancelled
&& parse_state
->parse_stack_length
> 0)
120 int ch
= parse_state
->buffer
->buf
[parse_state
->offset
];
121 //printf("Offset: %d, char %c\n", parse_state->offset, ch);
122 int found_transition
= 0;
124 /* We've read one character, which should cause one transition in the DFA for terminals.
125 * Find the appropriate transition, and put the DFA in its new state. */
126 for(int i
= 0; i
< parse_state
->dfa_state
->num_transitions
; i
++)
128 struct intfa_transition
*t
= &parse_state
->dfa_state
->transitions
[i
];
130 if(ch
>= t
->ch_low
&& ch
<= t
->ch_high
)
132 parse_state
->dfa_state
= t
->dest_state
;
133 found_transition
= 1;
140 if(parse_state
->dfa_state
->final
)
142 parse_state
->last_match_state
= parse_state
->dfa_state
;
143 parse_state
->last_match_end
= parse_state
->offset
;
145 parse_state
->offset
++;
149 /* if there was a previous match, fall back to that. otherwise this character represents
151 if(parse_state
->last_match_state
)
153 /* we have a terminal. do RTN transitions as appropriate */
154 //int terminal_len = parse_state->last_match_end-parse_state->match_begin+1;
155 //char terminal[terminal_len];
156 //memcpy(terminal, parse_state->buffer->buf+parse_state->match_begin, terminal_len);
157 //terminal[terminal_len] = '\0';
158 //printf("Recognized a terminal (%s) (%s)\n", parse_state->last_match_state->final, terminal);
159 parse_state
->offset
= parse_state
->last_match_end
+ 1;
160 do_rtn_transition(parse_state
, parse_state
->match_begin
, parse_state
->last_match_end
,
161 parse_state
->last_match_state
->final
);
165 printf("Syntax error!");
173 * c-file-style: "bsd"
175 * indent-tabs-mode: nil