https://github.com/charguer/ocaml
Raw File
Tip revision: 786012623dedd375982038aefabda0cc2621afcc authored by No author on 15 March 1996, 17:35:36 UTC
This commit was manufactured by cvs2svn to create tag 'rel115'.
Tip revision: 7860126
lexing.c
/***********************************************************************/
/*                                                                     */
/*                         Caml Special Light                          */
/*                                                                     */
/*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
/*                                                                     */
/*  Copyright 1995 Institut National de Recherche en Informatique et   */
/*  Automatique.  Distributed only by permission.                      */
/*                                                                     */
/***********************************************************************/

/* $Id$ */

/* The table-driven automaton for lexers generated by camllex. */

#include "mlvalues.h"
#include "stacks.h"
#include "str.h"

struct lexer_buffer {
  value refill_buff;
  value lex_buffer;
  value lex_buffer_len;
  value lex_abs_pos;
  value lex_start_pos;
  value lex_curr_pos;
  value lex_last_pos;
};

struct lexing_table {
  value lex_base;
  value lex_backtrk;
  value lex_default;
  value lex_trans;
  value lex_check;
};

#ifdef BIG_ENDIAN
#define Short(tbl,n) \
  (*((unsigned char *)((tbl) + (n) * sizeof(short))) + \
          (*((schar *)((tbl) + (n) * sizeof(short) + 1)) << 8))
#else
#define Short(tbl,n) (((short *)(tbl))[n])
#endif

value lex_engine(tbl, start_state, lexbuf)     /* ML */
     struct lexing_table * tbl;
     value start_state;
     struct lexer_buffer * lexbuf;
{
  int state, last_action, base, backtrk, c;
  
  state = Int_val(start_state);
  lexbuf->lex_last_pos = lexbuf->lex_start_pos = lexbuf->lex_curr_pos;
  last_action = -1;
  while(1) {
    /* Lookup base address or action number for current state */
    base = Short(tbl->lex_base, state);
    if (base < 0) return Val_int(-base-1);
    /* See if it's a backtrack point */
    backtrk = Short(tbl->lex_backtrk, state);
    if (backtrk >= 0) {
      lexbuf->lex_last_pos = lexbuf->lex_curr_pos;
      last_action = backtrk;
    }
    /* Read next input char */
    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 ();
    }
    c = Byte_u(lexbuf->lex_buffer, Long_val(lexbuf->lex_curr_pos));
    lexbuf->lex_curr_pos += 2;
    /* Determine next state */
    if (Short(tbl->lex_check, base + c) == state)
      state = Short(tbl->lex_trans, base + c);
    else
      state = Short(tbl->lex_default, state);
    /* 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);
    }
  }
}

back to top