Blame mallex.c

Packit d394d9
/* Copyright (C) 1995 Bjoern Beutel. */
Packit d394d9
Packit d394d9
/* Description. =============================================================*/
Packit d394d9
Packit d394d9
/* This program takes a lexicon file and compiles it to binary format. 
Packit d394d9
 * It also includes an interactive allomorph rules debugger. */
Packit d394d9
Packit d394d9
/* Includes. ================================================================*/
Packit d394d9
Packit d394d9
#include <stdio.h>
Packit d394d9
#include <stdarg.h>
Packit d394d9
#include <string.h>
Packit d394d9
#include <stdlib.h>
Packit d394d9
#include <setjmp.h>
Packit d394d9
#include <time.h>
Packit d394d9
#include <glib.h>
Packit d394d9
#include "basic.h"
Packit d394d9
#include "pools.h"
Packit d394d9
#include "values.h"
Packit d394d9
#include "symbols.h"
Packit d394d9
#include "scanner.h"
Packit d394d9
#include "rule_type.h"
Packit d394d9
#include "rules.h"
Packit d394d9
#include "files.h"
Packit d394d9
#include "lex_compiler.h"
Packit d394d9
#include "input.h"
Packit d394d9
#include "commands.h"
Packit d394d9
#include "commands_interactive.h"
Packit d394d9
#include "options.h"
Packit d394d9
#include "breakpoints.h"
Packit d394d9
#include "debugger.h"
Packit d394d9
#include "display.h"
Packit d394d9
#include "transmit.h"
Packit d394d9
#include "patterns.h"
Packit d394d9
#include "hangul.h"
Packit d394d9
Packit d394d9
/* Variables. ===============================================================*/
Packit d394d9
Packit d394d9
static string_t allo_format; /* Format of allomorph output. */
Packit d394d9
Packit d394d9
static bool_t lex_tree_to_output = FALSE;
Packit d394d9
/* Indicates whether the lexicon tree can be printed. */
Packit d394d9
Packit d394d9
static string_t lexicon_file, rule_file, symbol_file, project_file;
Packit d394d9
static string_t prelex_file;
Packit d394d9
Packit d394d9
static string_t base_feat_string; /* Last base feature structure. */
Packit d394d9
Packit d394d9
/* Functions. ===============================================================*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
display_where( void )
Packit d394d9
/* Print the name of the current rule. */
Packit d394d9
{ 
Packit d394d9
  string_t file, rule;
Packit d394d9
  int_t line;
Packit d394d9
Packit d394d9
  source_of_instr( executed_rule_sys, pc, &line, &file, &rule );
Packit d394d9
  printf( "At \"%s\", line %d, rule \"%s\".", 
Packit d394d9
	  name_in_path( file ), line, rule );
Packit d394d9
  if (lex_entry_file_name != NULL) 
Packit d394d9
  { 
Packit d394d9
    printf( " (\"%s\", line %d)", 
Packit d394d9
	    name_in_path( lex_entry_file_name ), lex_entry_line_number );
Packit d394d9
  }
Packit d394d9
  printf( "\n" );
Packit d394d9
  if (in_emacs_malaga_mode) 
Packit d394d9
    printf( "SHOW \"%s\":%d:0\n", file, line );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void
Packit d394d9
read_lexicon_file_name( string_t *arguments )
Packit d394d9
{
Packit d394d9
  if (**arguments != EOS)
Packit d394d9
  {
Packit d394d9
    free_mem( &lexicon_file );
Packit d394d9
    lexicon_file = parse_absolute_path( arguments, NULL );
Packit d394d9
  }
Packit d394d9
  if (lexicon_file == NULL)
Packit d394d9
    complain( "Missing lexicon file name." );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
display_result( void )
Packit d394d9
/* Display result in the modes that have been switched on after analysis. */
Packit d394d9
{ 
Packit d394d9
  if (use_display) 
Packit d394d9
  { 
Packit d394d9
    start_display_process();
Packit d394d9
    fprintf( display_stream, "allomorph\n" );
Packit d394d9
    print_lex_buffer( display_stream, "%n %s {%f}" );
Packit d394d9
    fprintf( display_stream, "end\n" );
Packit d394d9
    fflush( display_stream );
Packit d394d9
  } 
Packit d394d9
  else 
Packit d394d9
    print_lex_buffer( stdout, NULL );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_result( string_t arguments )
Packit d394d9
/* Show result of last allomorph generation. */
Packit d394d9
{ 
Packit d394d9
  parse_end( &arguments );
Packit d394d9
  if (! lex_tree_to_output) 
Packit d394d9
    complain( "No previous allomorph generation." );
Packit d394d9
  display_result();
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t result_command = 
Packit d394d9
{ 
Packit d394d9
  "result res", do_result,
Packit d394d9
  "Show result of last allomorph generation.\n"
Packit d394d9
  "Usage: result\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_read_constants( string_t arguments )
Packit d394d9
/* Read the constants in the lexicon with name on line ARGUMENTS. */
Packit d394d9
{ 
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  read_lexicon_file_name( &arguments );
Packit d394d9
  parse_end( &arguments );
Packit d394d9
  read_lex_constants( lexicon_file );
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t read_constants_command = 
Packit d394d9
{ 
Packit d394d9
  "read-constants", do_read_constants,
Packit d394d9
  "Read the constants from the definitions in a lexicon file.\n"
Packit d394d9
  "Usage: read-constants [LEXICON_FILE]\n"
Packit d394d9
  "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n"
Packit d394d9
  "\"read-constants\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_ga_file( string_t arguments )
Packit d394d9
/* Generate allomorphs of a base lexicon.
Packit d394d9
 * Write the allomorphs readably into file. */
Packit d394d9
{ 
Packit d394d9
  string_t output_name;
Packit d394d9
  FILE *output_stream;
Packit d394d9
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
Packit d394d9
  output_stream = NULL;
Packit d394d9
  output_name = NULL;
Packit d394d9
  TRY 
Packit d394d9
  { 
Packit d394d9
    read_lexicon_file_name( &arguments );
Packit d394d9
    if (*arguments != EOS) 
Packit d394d9
      output_name = parse_absolute_path( &arguments, NULL );
Packit d394d9
    parse_end( &arguments );
Packit d394d9
Packit d394d9
    set_debug_mode( RUN_MODE, NULL );
Packit d394d9
    lex_tree_to_output = FALSE;
Packit d394d9
    generate_allos_for_file( lexicon_file, NULL, TRUE );
Packit d394d9
    lex_tree_to_output = TRUE;
Packit d394d9
Packit d394d9
    if (output_name != NULL)
Packit d394d9
    {
Packit d394d9
      output_stream = open_stream( output_name, "w" );
Packit d394d9
      print_lex_buffer( output_stream, allo_format );
Packit d394d9
      print_lex_statistics( stdout );
Packit d394d9
      close_stream( &output_stream, output_name );
Packit d394d9
    }
Packit d394d9
  } 
Packit d394d9
  FINALLY 
Packit d394d9
  { 
Packit d394d9
    close_stream( &output_stream, NULL );
Packit d394d9
    free_mem( &output_name );
Packit d394d9
  }
Packit d394d9
  END_TRY;
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t ga_file_command = 
Packit d394d9
{ 
Packit d394d9
  "ga-file gaf", do_ga_file,
Packit d394d9
  "Generate allomorphs from the entries in a lexicon file.\n"
Packit d394d9
  "Usage: ga-file [LEXICON_FILE [ALLO_FILE]]\n"
Packit d394d9
  "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n"
Packit d394d9
  "If ALLO_FILE is given, the results are written to \"ALLO_FILE\".\n"
Packit d394d9
  "The results can also be displayed by the command \"result\".\n"
Packit d394d9
  "\"ga-file\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_debug_ga_file( string_t arguments )
Packit d394d9
/* Generate allomorphs of the base lexicon with name in ARGUMENTS.
Packit d394d9
 * Execute rules in debug mode. */
Packit d394d9
{ 
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  read_lexicon_file_name( &arguments );
Packit d394d9
  parse_end( &arguments );
Packit d394d9
  set_debug_mode( WALK_MODE, allo_rule_sys );
Packit d394d9
  lex_tree_to_output = FALSE;
Packit d394d9
  generate_allos_for_file( lexicon_file, NULL, TRUE );
Packit d394d9
  lex_tree_to_output = TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t debug_ga_file_command = 
Packit d394d9
{ 
Packit d394d9
  "debug-ga-file dgaf", do_debug_ga_file,
Packit d394d9
  "Generate allomorphs from the entries in a lexicon file.\n"
Packit d394d9
  "Execute the rules in debug mode.\n"
Packit d394d9
  "Usage: debug-ga-file [LEXICON_FILE]\n"
Packit d394d9
  "If LEXICON_FILE is omitted, the previous lexicon file name is used.\n"
Packit d394d9
  "\"debug-ga-file\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
generate_allomorphs_for_line( string_t arguments )
Packit d394d9
/* Generate allomorphs for ARGUMENTS, which should consist
Packit d394d9
 * of a file name and a line number. */
Packit d394d9
{ 
Packit d394d9
  int_t line;
Packit d394d9
Packit d394d9
  line = parse_cardinal( &arguments );
Packit d394d9
  read_lexicon_file_name( &arguments );
Packit d394d9
  parse_end( &arguments );
Packit d394d9
  lex_tree_to_output = FALSE;
Packit d394d9
  generate_allos_for_line( lexicon_file, line );
Packit d394d9
  lex_tree_to_output = TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_ga_line( string_t arguments )
Packit d394d9
/* Generate allomorphs for ARGUMENTS, which should consist
Packit d394d9
 * of a file name and a line number. */
Packit d394d9
{ 
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  set_debug_mode( RUN_MODE, NULL );
Packit d394d9
  generate_allomorphs_for_line( arguments );
Packit d394d9
  display_result();
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t ga_line_command = 
Packit d394d9
{ 
Packit d394d9
  "ga-line gal", do_ga_line,
Packit d394d9
  "Generate allomorphs from a single entry in a file.\n"
Packit d394d9
  "Usage: ga-line LINE [FILE]\n"
Packit d394d9
  "The first lexicon entry at or behind LINE in FILE is read in.\n"
Packit d394d9
  "If FILE is omitted, the previous file name is used.\n"
Packit d394d9
  "\"ga-line\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_debug_ga_line( string_t arguments )
Packit d394d9
/* Generate an allomorph for ARGUMENTS, which should consist
Packit d394d9
 * of a file name and a line number, in debugger mode. */
Packit d394d9
{ 
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  set_debug_mode( WALK_MODE, allo_rule_sys );
Packit d394d9
  generate_allomorphs_for_line( arguments );
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t debug_ga_line_command = 
Packit d394d9
{ 
Packit d394d9
  "debug-ga-line dgal", do_debug_ga_line,
Packit d394d9
  "Generate allomorphs from a single entry in a file.\n"
Packit d394d9
  "Execute allomorph rules in debug mode.\n"
Packit d394d9
  "Usage: debug-ga-line LINE [FILE]\n"
Packit d394d9
  "The first lexicon entry at or behind LINE in FILE is read in.\n"
Packit d394d9
  "Allomorph rule execution stops at the first statement.\n"
Packit d394d9
  "If FILE is omitted, the previous file name is used.\n"
Packit d394d9
  "\"debug-line\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
generate_allomorphs( string_t arguments )
Packit d394d9
/* Generate allomorphs for lexicon entry ARGUMENTS. */
Packit d394d9
{ 
Packit d394d9
  /* If no argument given, re-analyze last argument */
Packit d394d9
  if (*arguments == EOS) 
Packit d394d9
  { 
Packit d394d9
    if (base_feat_string == NULL) 
Packit d394d9
      complain( "No previous base feature structure." );
Packit d394d9
  } 
Packit d394d9
  else 
Packit d394d9
  { 
Packit d394d9
    free_mem( &base_feat_string );
Packit d394d9
    base_feat_string = new_string( arguments, NULL );
Packit d394d9
  }
Packit d394d9
  lex_tree_to_output = FALSE;
Packit d394d9
  generate_allos_for_string( base_feat_string );
Packit d394d9
  lex_tree_to_output = TRUE;
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_ga( string_t arguments )
Packit d394d9
/* Generate allomorphs for ARGUMENTS. */
Packit d394d9
{ 
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  set_debug_mode( RUN_MODE, NULL );
Packit d394d9
  generate_allomorphs( arguments );
Packit d394d9
  display_result();
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t ga_command = 
Packit d394d9
{ 
Packit d394d9
  "ga", do_ga,
Packit d394d9
  "Generate allomorphs from a feature structure argument.\n"
Packit d394d9
  "Usage:\n"
Packit d394d9
  "  ga FEAT -- Generate allomorphs for feature structure FEAT.\n"
Packit d394d9
  "  ga -- Re-generate allomorphs for the last argument.\n"
Packit d394d9
  "The allomorphs are shown on screen.\n"
Packit d394d9
  "\"ga\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_debug_ga( string_t arguments )
Packit d394d9
/* Generate allomorphs for ARGUMENTS.
Packit d394d9
 * Execute allomorph rules in debug mode. */
Packit d394d9
{
Packit d394d9
  assert_not_in_debug_mode();
Packit d394d9
  set_debug_mode( WALK_MODE, allo_rule_sys );
Packit d394d9
  generate_allomorphs( arguments );
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t debug_ga_command = 
Packit d394d9
{ 
Packit d394d9
  "debug-ga dga ga-debug gad", do_debug_ga,
Packit d394d9
  "Generate allomorphs from the feature structure argument. "
Packit d394d9
  "Execute allomorph rules in debug mode.\n"
Packit d394d9
  "Usage:\n"
Packit d394d9
  "  debug-ga FEAT -- Generate allomorphs for feature structure FEAT.\n"
Packit d394d9
  "  debug-ga -- Re-generate allomorphs for the last argument.\n"
Packit d394d9
  "Rule execution stops at the first statement.\n"
Packit d394d9
  "The allomorphs are shown on screen.\n"
Packit d394d9
  "\"debug-ga\" can't be used in debug mode.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
do_allo_format_option( string_t arguments ) 
Packit d394d9
/* Change allomorph output line to "arguments" */
Packit d394d9
{ 
Packit d394d9
  string_t format;
Packit d394d9
Packit d394d9
  if (*arguments == EOS) 
Packit d394d9
  { 
Packit d394d9
    format = new_string_readable( allo_format, NULL );
Packit d394d9
    printf( "allo-format: %s\n", format );
Packit d394d9
    free_mem( &format );
Packit d394d9
  } 
Packit d394d9
  else 
Packit d394d9
  { 
Packit d394d9
    format = parse_word( &arguments );
Packit d394d9
    free_mem( &allo_format );
Packit d394d9
    allo_format = format;
Packit d394d9
  }
Packit d394d9
}
Packit d394d9
Packit d394d9
static command_t allo_format_option = 
Packit d394d9
{ 
Packit d394d9
  "allo-format", do_allo_format_option,
Packit d394d9
  "Describe the format in which generated allomorphs will be printed.\n"
Packit d394d9
  "Usage: allo-format STRING\n"
Packit d394d9
  "STRING may contain the following special sequences:\n"
Packit d394d9
  "  %f -- Allomorph feature structure.\n"
Packit d394d9
  "  %n -- Allomorph number.\n"
Packit d394d9
  "  %s -- Allomorph surface.\n"
Packit d394d9
};
Packit d394d9
Packit d394d9
/* Commands. ================================================================*/
Packit d394d9
Packit d394d9
static command_t *mallex_options[] = 
Packit d394d9
{ 
Packit d394d9
  &alias_option, &allo_format_option, &auto_variables_option, 
Packit d394d9
  &display_cmd_option, &hidden_option, &roman_hangul_option, 
Packit d394d9
  &sort_records_option, &switch_option, &transmit_cmd_option, 
Packit d394d9
  &use_display_option,
Packit d394d9
  NULL
Packit d394d9
};
Packit d394d9
Packit d394d9
static command_t *mallex_commands[] = 
Packit d394d9
{ 
Packit d394d9
  &backtrace_command, &break_command, &continue_command, &debug_ga_command, 
Packit d394d9
  &debug_ga_file_command, &debug_ga_line_command, &delete_command, 
Packit d394d9
  &down_command, &finish_command, &frame_command, &ga_command, 
Packit d394d9
  &ga_file_command, &ga_line_command, &get_command, &help_command, 
Packit d394d9
  &list_command, &next_command, &print_command, &quit_command, 
Packit d394d9
  &read_constants_command, &result_command, &run_command, &set_command, 
Packit d394d9
  &step_command, &transmit_command, &up_command, &variables_command, 
Packit d394d9
  &walk_command, &where_command,
Packit d394d9
  NULL
Packit d394d9
};
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
static void 
Packit d394d9
read_project_file( string_t file_name )
Packit d394d9
/* Read the project file FILE_NAME. */
Packit d394d9
{ 
Packit d394d9
  FILE *project_stream;
Packit d394d9
  string_t include_file;
Packit d394d9
  string_t project_line_p, argument, extension;
Packit d394d9
  char_t *project_line;
Packit d394d9
  string_t *name_p;
Packit d394d9
  volatile bool_t binary = FALSE;
Packit d394d9
  volatile int_t line_count;
Packit d394d9
  static bool_t err_pos_printed;
Packit d394d9
Packit d394d9
  err_pos_printed = FALSE;
Packit d394d9
  project_stream = open_stream( file_name, "r" );
Packit d394d9
  line_count = 0;
Packit d394d9
  while (TRUE) 
Packit d394d9
  { 
Packit d394d9
    TRY
Packit d394d9
      project_line = read_line( project_stream );
Packit d394d9
    IF_ERROR
Packit d394d9
    {
Packit d394d9
      print_text( error_text, " (\"%s\", line %d)",
Packit d394d9
		  name_in_path( file_name ), line_count + 1 );
Packit d394d9
      err_pos_printed = TRUE;
Packit d394d9
    }
Packit d394d9
    END_TRY;
Packit d394d9
    if (project_line == NULL) 
Packit d394d9
      break;
Packit d394d9
    line_count++;
Packit d394d9
    cut_comment( project_line );
Packit d394d9
    project_line_p = project_line;
Packit d394d9
Packit d394d9
    if (*project_line_p != EOS) 
Packit d394d9
    { 
Packit d394d9
      argument = NULL;
Packit d394d9
      TRY
Packit d394d9
      {
Packit d394d9
	argument = parse_word( &project_line_p );
Packit d394d9
	extension = NULL;
Packit d394d9
	name_p = NULL;
Packit d394d9
	if (strcmp_no_case( argument, "sym:" ) == 0) 
Packit d394d9
	{ 
Packit d394d9
	  name_p = &symbol_file;
Packit d394d9
	  extension = "sym";
Packit d394d9
	  binary = TRUE;
Packit d394d9
	} 
Packit d394d9
	else if (strcmp_no_case( argument, "lex:" ) == 0) 
Packit d394d9
	{
Packit d394d9
	  name_p = &lexicon_file;
Packit d394d9
	  extension = "lex";
Packit d394d9
	  binary = FALSE;
Packit d394d9
	}
Packit d394d9
	else if (strcmp_no_case( argument, "all:" ) == 0) 
Packit d394d9
	{ 
Packit d394d9
	  name_p = &rule_file;
Packit d394d9
	  extension = "all";
Packit d394d9
	  binary = TRUE;
Packit d394d9
	} 
Packit d394d9
	else if (strcmp_no_case( argument, "prelex:" ) == 0)
Packit d394d9
	{
Packit d394d9
	  if (prelex_file != NULL) 
Packit d394d9
	    complain( "Prelex file already defined." );
Packit d394d9
	  name_p = &prelex_file;
Packit d394d9
	  extension = "prelex";
Packit d394d9
	  binary = TRUE;
Packit d394d9
	}
Packit d394d9
	else if (strcmp_no_case( argument, "include:" ) == 0) 
Packit d394d9
	{ 
Packit d394d9
	  include_file = parse_absolute_path( &project_line_p, file_name );
Packit d394d9
	  parse_end( &project_line_p );
Packit d394d9
	  read_project_file( include_file );
Packit d394d9
	  free_mem( &include_file );
Packit d394d9
	}
Packit d394d9
	free_mem( &argument );
Packit d394d9
Packit d394d9
	if (name_p != NULL && *name_p == NULL && *project_line_p != EOS) 
Packit d394d9
	{ 
Packit d394d9
	  argument = parse_absolute_path( &project_line_p, file_name );
Packit d394d9
	  if (! has_extension( argument, extension ))
Packit d394d9
	  {
Packit d394d9
	    complain( "\"%s\" should have extension \"%s\".", 
Packit d394d9
		      name_in_path( argument ), extension );
Packit d394d9
	  }
Packit d394d9
	  if (binary) 
Packit d394d9
	    set_binary_file_name( name_p, argument );
Packit d394d9
	  else 
Packit d394d9
	    set_file_name( name_p, argument );
Packit d394d9
	  free_mem( &argument );
Packit d394d9
	}
Packit d394d9
      }
Packit d394d9
      IF_ERROR
Packit d394d9
      {
Packit d394d9
	if (! err_pos_printed)
Packit d394d9
	{
Packit d394d9
	  print_text( error_text, " (\"%s\", line %d)",
Packit d394d9
		      name_in_path( file_name ), line_count );
Packit d394d9
	  err_pos_printed = TRUE;
Packit d394d9
	}
Packit d394d9
      }
Packit d394d9
      END_TRY;
Packit d394d9
    }
Packit d394d9
    free_mem( &project_line );
Packit d394d9
  }
Packit d394d9
  close_stream( &project_stream, file_name );
Packit d394d9
}
Packit d394d9
Packit d394d9
/*---------------------------------------------------------------------------*/
Packit d394d9
Packit d394d9
int 
Packit d394d9
main( int argc, char *argv[] )
Packit d394d9
/* The main function of "mallex". */
Packit d394d9
{ 
Packit d394d9
  volatile enum {INTERACTIVE_MODE, BINARY_MODE, TEXT_MODE, 
Packit d394d9
		 PRELEX_MODE} mallex_mode;
Packit d394d9
  int_t i;
Packit d394d9
  string_t malagarc_path, s;
Packit d394d9
  rule_sys_name_t rule_systems[1]; /* Rule system for debugger. */
Packit d394d9
  string_t object_file = NULL; /* Object file for binary and prelex mode. */
Packit d394d9
    
Packit d394d9
  mallex_mode = INTERACTIVE_MODE;
Packit d394d9
  init_basic( "mallex" );
Packit d394d9
  init_input();
Packit d394d9
Packit d394d9
  /* Parse arguments. */
Packit d394d9
  if (argc == 2) 
Packit d394d9
  { 
Packit d394d9
    if (strcmp_no_case( argv[1], "--version" ) == 0
Packit d394d9
	|| strcmp_no_case( argv[1], "-version" ) == 0
Packit d394d9
	|| strcmp_no_case( argv[1], "-v" ) == 0)  
Packit d394d9
    { 
Packit d394d9
      program_message();
Packit d394d9
      exit( 0 );
Packit d394d9
    } 
Packit d394d9
    else if (strcmp_no_case( argv[1], "--help" ) == 0
Packit d394d9
	     || strcmp_no_case( argv[1], "-help" ) == 0
Packit d394d9
	     || strcmp_no_case( argv[1], "-h" ) == 0) 
Packit d394d9
    { 
Packit d394d9
      printf( "Apply the allomorph rules on the entries of a Malaga lexicon.\n"
Packit d394d9
	      "\n"
Packit d394d9
	      "Usage:\n"
Packit d394d9
	      "mallex GRAMMAR             "
Packit d394d9
	      "-- Start interactive mallex.\n"
Packit d394d9
	      "mallex GRAMMAR -b[inary]   "
Packit d394d9
	      "-- Create binary allomorph lexicon.\n"
Packit d394d9
	      "mallex GRAMMAR -r[eadable] "
Packit d394d9
	      "-- Output readable allomorph lexicon.\n"
Packit d394d9
	      "mallex GRAMMAR -p[relex]   "
Packit d394d9
	      "-- Output precompiled lexicon.\n"
Packit d394d9
	      "mallex -v[ersion]          "
Packit d394d9
	      "-- Print version information.\n"
Packit d394d9
	      "mallex -h[elp]             "
Packit d394d9
	      "-- Print this help.\n\n"
Packit d394d9
	      "GRAMMAR may be \"PROJECT_FILE\" "
Packit d394d9
	      "or \"SYM_FILE ALLO_FILE LEX_FILE [PRELEX_FILE]\".\n"
Packit d394d9
	      "PROJECT_FILE must end on \".pro\".\n"
Packit d394d9
	      "SYM_FILE must end on \".sym\".\n"
Packit d394d9
	      "ALLO_FILE must end on \".all\".\n"
Packit d394d9
	      "LEX_FILE must end on \".lex\".\n"
Packit d394d9
	      "PRELEX_FILE must end on \".prelex\".\n" );
Packit d394d9
      exit( 0 );
Packit d394d9
    }
Packit d394d9
  }
Packit d394d9
  for (i = 1; i < argc; i++) 
Packit d394d9
  { 
Packit d394d9
    if (has_extension( argv[i], "pro" )) 
Packit d394d9
      set_file_name( &project_file, argv[i] ); 
Packit d394d9
    else if (has_extension( argv[i], "lex" )) 
Packit d394d9
      set_file_name( &lexicon_file, argv[i] );
Packit d394d9
    else if (has_extension( argv[i], "all" )) 
Packit d394d9
      set_binary_file_name( &rule_file, argv[i] );
Packit d394d9
    else if (has_extension( argv[i], "sym" )) 
Packit d394d9
      set_binary_file_name( &symbol_file, argv[i] );
Packit d394d9
    else if (has_extension( argv[i], "prelex") )
Packit d394d9
      set_binary_file_name( &prelex_file, argv[i] );
Packit d394d9
    else if (strcmp_no_case( argv[i], "-binary" ) == 0
Packit d394d9
	     || strcmp_no_case( argv[i], "-b" ) == 0) 
Packit d394d9
    { 
Packit d394d9
      mallex_mode = BINARY_MODE; 
Packit d394d9
    } 
Packit d394d9
    else if (strcmp_no_case( argv[i], "-readable" ) == 0
Packit d394d9
	     || strcmp_no_case( argv[i], "-r" ) == 0) 
Packit d394d9
    { 
Packit d394d9
      mallex_mode = TEXT_MODE; 
Packit d394d9
    } 
Packit d394d9
    else if (strcmp_no_case( argv[i], "-prelex" ) == 0
Packit d394d9
	     || strcmp_no_case( argv[i], "-p" ) == 0) 
Packit d394d9
    { 
Packit d394d9
      mallex_mode = PRELEX_MODE; 
Packit d394d9
    } 
Packit d394d9
    else 
Packit d394d9
      complain( "Illegal argument \"%s\".", argv[i] );
Packit d394d9
  }
Packit d394d9
  if (project_file != NULL) 
Packit d394d9
    read_project_file( project_file );
Packit d394d9
  if (rule_file == NULL) 
Packit d394d9
    complain( "Missing allomorph rule file name." );
Packit d394d9
  if (symbol_file == NULL) 
Packit d394d9
    complain( "Missing symbol file name." );
Packit d394d9
Packit d394d9
  /* Init modules. */
Packit d394d9
  init_values();
Packit d394d9
  init_symbols( symbol_file );
Packit d394d9
  init_hangul();
Packit d394d9
  init_transmit();
Packit d394d9
  init_lex_compiler( rule_file );
Packit d394d9
  init_scanner();
Packit d394d9
Packit d394d9
  /* Set mallex options to default values. */
Packit d394d9
  options = mallex_options;
Packit d394d9
  allo_format = new_string( "%s: %f", NULL );
Packit d394d9
  use_display = FALSE;
Packit d394d9
Packit d394d9
  /* Set mallex options by user scripts. */
Packit d394d9
  if (project_file != NULL) 
Packit d394d9
    execute_set_commands( project_file, "mallex:" );
Packit d394d9
  malagarc_path = NULL;
Packit d394d9
#ifdef POSIX
Packit d394d9
  TRY 
Packit d394d9
    malagarc_path = absolute_path( "~/.malagarc", NULL );
Packit d394d9
  IF_ERROR 
Packit d394d9
    RESUME;
Packit d394d9
  END_TRY;
Packit d394d9
#endif
Packit d394d9
#ifdef WIN32
Packit d394d9
  TRY 
Packit d394d9
    malagarc_path = absolute_path( "~\\malaga.ini", NULL );
Packit d394d9
  IF_ERROR 
Packit d394d9
    RESUME;
Packit d394d9
  END_TRY;
Packit d394d9
#endif
Packit d394d9
  if (malagarc_path != NULL && file_exists( malagarc_path ))
Packit d394d9
    execute_set_commands( malagarc_path, "mallex:" );
Packit d394d9
  free_mem( &malagarc_path );
Packit d394d9
Packit d394d9
  if (mallex_mode == INTERACTIVE_MODE) 
Packit d394d9
  { 
Packit d394d9
    init_debugger( display_where, mallex_commands );
Packit d394d9
    rule_systems[0].rule_sys = allo_rule_sys;
Packit d394d9
    rule_systems[0].name = "all";
Packit d394d9
    init_breakpoints( 1, rule_systems );
Packit d394d9
    program_message();
Packit d394d9
    command_loop( program_name, mallex_commands );
Packit d394d9
    terminate_breakpoints();
Packit d394d9
    terminate_debugger();
Packit d394d9
  } 
Packit d394d9
  else 
Packit d394d9
  { 
Packit d394d9
    if (lexicon_file == NULL) 
Packit d394d9
      complain( "missing lexicon file name" );
Packit d394d9
    switch (mallex_mode)
Packit d394d9
    {
Packit d394d9
    case TEXT_MODE:
Packit d394d9
      generate_allos_for_file( lexicon_file, NULL, TRUE );
Packit d394d9
      print_lex_buffer( stdout, allo_format );
Packit d394d9
      break;
Packit d394d9
    case BINARY_MODE:
Packit d394d9
      generate_allos_for_file( lexicon_file, prelex_file, TRUE );
Packit d394d9
      set_binary_file_name( &object_file, lexicon_file );
Packit d394d9
      write_lex_buffer( object_file );
Packit d394d9
      free_mem( &object_file );
Packit d394d9
      break;
Packit d394d9
    case PRELEX_MODE:
Packit d394d9
      generate_allos_for_file( lexicon_file, prelex_file, FALSE );
Packit d394d9
      s = replace_extension( lexicon_file, "prelex" );
Packit d394d9
      set_binary_file_name( &object_file, s );
Packit d394d9
      free_mem( &s );
Packit d394d9
      write_prelex_file( object_file );
Packit d394d9
      free_mem( &object_file );
Packit d394d9
      break;
Packit d394d9
    default:
Packit d394d9
      complain( "Internal error." );
Packit d394d9
    }
Packit d394d9
    print_lex_statistics( stderr );
Packit d394d9
  }
Packit d394d9
Packit d394d9
  free_aliases();
Packit d394d9
  free_mem( &base_feat_string );
Packit d394d9
  free_mem( &allo_format );
Packit d394d9
  stop_display_process();
Packit d394d9
  terminate_lex_compiler();
Packit d394d9
  terminate_hangul();
Packit d394d9
  terminate_symbols();
Packit d394d9
  terminate_transmit();
Packit d394d9
  terminate_values();
Packit d394d9
  terminate_scanner();
Packit d394d9
  terminate_patterns();
Packit d394d9
  free_switches();
Packit d394d9
  free_mem( &rule_file );
Packit d394d9
  free_mem( &symbol_file );
Packit d394d9
  free_mem( &lexicon_file );
Packit d394d9
  free_mem( &project_file );
Packit d394d9
  terminate_input();
Packit d394d9
  terminate_basic();
Packit d394d9
  return 0;
Packit d394d9
}
Packit d394d9
Packit d394d9
/* End of file. =============================================================*/