summaryrefslogtreecommitdiffstats
path: root/byterun/lexing.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/lexing.c')
-rw-r--r--byterun/lexing.c36
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;
+ }
}
}
}