diff options
Diffstat (limited to 'byterun/lexing.c')
-rw-r--r-- | byterun/lexing.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/byterun/lexing.c b/byterun/lexing.c index 8a3219f6c..86387a911 100644 --- a/byterun/lexing.c +++ b/byterun/lexing.c @@ -13,6 +13,7 @@ /* The table-driven automaton for lexers generated by camllex. */ +#include "fail.h" #include "mlvalues.h" #include "stacks.h" #include "str.h" @@ -25,6 +26,8 @@ struct lexer_buffer { value lex_start_pos; value lex_curr_pos; value lex_last_pos; + value lex_saved_state; + value lex_last_action; }; struct lexing_table { @@ -48,11 +51,16 @@ value lex_engine(tbl, start_state, lexbuf) /* ML */ value start_state; struct lexer_buffer * lexbuf; { - int state, last_action, base, backtrk, c; + int state, base, backtrk, c; - state = Int_val(start_state); - lexbuf->lex_last_pos = lexbuf->lex_start_pos = lexbuf->lex_curr_pos; - last_action = -1; + if (Int_val(lexbuf->lex_saved_state) >= 0) { + state = Int_val(lexbuf->lex_saved_state); + lexbuf->lex_saved_state = Val_int(-1); + } else { + state = Int_val(start_state); + lexbuf->lex_last_pos = lexbuf->lex_start_pos = lexbuf->lex_curr_pos; + lexbuf->lex_last_action = Val_int(-1); + } while(1) { /* Lookup base address or action number for current state */ base = Short(tbl->lex_base, state); @@ -61,18 +69,14 @@ value lex_engine(tbl, start_state, lexbuf) /* ML */ backtrk = Short(tbl->lex_backtrk, state); if (backtrk >= 0) { lexbuf->lex_last_pos = lexbuf->lex_curr_pos; - last_action = backtrk; + lexbuf->lex_last_action = Val_int(backtrk); } - /* Read next input char */ + /* See if we need a refill */ if (lexbuf->lex_curr_pos >= lexbuf->lex_buffer_len) { - Push_roots (r, 2); - r[0] = (value) tbl; - r[1] = (value) lexbuf; - callback(lexbuf->refill_buff, (value) lexbuf); - tbl = (struct lexing_table *) r[0]; - lexbuf = (struct lexer_buffer *) r[1]; - Pop_roots (); + lexbuf->lex_saved_state = Val_int(state); + return (-1); } + /* Read next input char */ c = Byte_u(lexbuf->lex_buffer, Long_val(lexbuf->lex_curr_pos)); lexbuf->lex_curr_pos += 2; /* Determine next state */ @@ -83,7 +87,11 @@ value lex_engine(tbl, start_state, lexbuf) /* ML */ /* If no transition on this char, return to last backtrack point */ if (state < 0) { lexbuf->lex_curr_pos = lexbuf->lex_last_pos; - return Val_int(last_action); + if (lexbuf->lex_last_action == Val_int(-1)) { + failwith("lexing: empty token"); + } else { + return lexbuf->lex_last_action; + } } } } |