/*
   File: lexicon_input.c
   Defines the various lexeme types and holds the character tables while lexing

   Copyright 2005 Radboud University of Nijmegen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Library General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   CVS ID: "$Id: lexicon_input.c,v 1.3 2006/09/27 16:01:31 marcs Exp $
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */

/* standard includes */
#include <stdio.h>
#include <ctype.h>
#include <string.h>

/* abase includes */
#include <abase_error.h>

/* local includes */
#include "lexicon_input.h"

/*------------------------------------------------------------------------------
// Global data
//----------------------------------------------------------------------------*/
static unsigned char        blank_table[256];
static unsigned char        terminator_table[256];
static unsigned char        invisible_table[256];
static unsigned char        translate_table[256];

/*------------------------------------------------------------------------------
// Table functions
//----------------------------------------------------------------------------*/
static void set_table (unsigned char* table, unsigned char* str)
{ unsigned char c;
  unsigned ix;
  if (str == NULL) abs_abort ("set_table", "called with NULL string");

  for (ix = 0; ix < 256; ix++) table[ix] = '\0';
  while ((c = *str++)) table[c] = c;
}

static void set_trans_table (unsigned char* table, unsigned char* src, unsigned char* dst)
{ unsigned char c;
  unsigned i;
  if (src == NULL || dst == NULL)
    abs_abort ("set_trans_table", "called with NULL string");

  for (i = 0; i < 256; i++) table[i] = i;
  while ((c = *src++)) table[c] = *dst++;
}

/*------------------------------------------------------------------------------
// Token types and markers
//----------------------------------------------------------------------------*/
unsigned char lxcn_get_lex_mark (LexemeType lex_type)
{ switch (lex_type)
    { case Prefix:	return (PrefixMark); break;
      case Infix:	return (InfixMark); break;
      case Suffix:	return (SuffixMark); break;
      case MultiToken:	return (MultiTokenMark); break;
      default:		return (EmptyMark);
    };
}

int lxcn_is_eos (unsigned char c)
{ return (c == EosMark);
}

int lxcn_is_space (unsigned char c)
{ return (c == SpaceMark);
}

int lxcn_is_blank (unsigned char c)
{ return (blank_table[(int) c] != '\0');
}

int lxcn_is_terminator (unsigned char c)
{ return (terminator_table[(int) c] != '\0');
}

int lxcn_is_invisible (unsigned char c)
{ return (invisible_table[(int) c] != '\0');
}

int lxcn_translate (unsigned char c)
{ return (translate_table[(int) c]);
}

void lxcn_init_char_tables (char *blanks, char *terminators, char *invisibles, 
			    char *translate_src, char *translate_dst)
{ set_table (blank_table, blanks);
  set_table (terminator_table, terminators);
  set_table (invisible_table, invisibles);
  set_trans_table (translate_table, translate_src, translate_dst);
  terminator_table[EosMark] = 1;
}

/*------------------------------------------------------------------------------
// Function:
//        int lxcn_check_terminator (SeparatorType sep_type, unsigned char c)
//
// Description:
//        Check whether c is allowed in the context of sep_type.
//        If sep_type is SepRequired, then c must be a terminator,
//        else, don't care.
//
// Return value:
//        True if c allowed with sep_type, or false else.
//----------------------------------------------------------------------------*/
int lxcn_check_terminator (SeparatorType sep_type, unsigned char c)
{ switch (sep_type)
    { case SepDontCare:	return (1);
      case SepRequired:	return (lxcn_is_terminator (c));
      default: abs_abort ("check_terminator", "bad sep_type %d", (int) sep_type);
    };
  return (0);
}


