1
/* Copyright (C) 1995 Bjoern Beutel. */
3
/* Description. =============================================================*/
5
/* This is the interactive program for morphological and syntactic analysis. */
7
/* Includes. ================================================================*/
21
#include "rule_type.h"
28
#include "malaga_lib.h"
29
#include "generation.h"
31
#include "breakpoints.h"
36
/* Macros. ==================================================================*/
38
#define SAFE_STRING(s) ((s) != NULL ? (s) : (string_t) "")
39
/* Return an empty string if S == NULL. */
41
/* Variables. ===============================================================*/
43
static string_t analysis_input; /* Input line for interactive analysis. */
45
static int_t debug_analysis_node_index; /* Index of state to debug or -1. */
47
static debug_mode_t state_debug_mode;
48
/* Debug mode to use for states to debug. */
50
/* Analysis result output. ==================================================*/
53
display_result( void )
54
/* Generate result file and start program to display result. */
57
string_t value_string;
58
string_t count_string;
62
if (! analysis_has_nodes())
63
complain( "No analysis started." );
65
/* Print analysis result header. */
66
input = new_string_readable( analysis_input, NULL );
67
decode_hangul( &input );
70
start_display_process();
71
fprintf( display_stream, "result\n" );
72
fprintf( display_stream, "%s\n", input );
76
if (! analysis_has_results())
77
printf( "No analyses of %s.\n", input );
79
printf( "Analyses of %s:\n", input );
83
/* Print analysis results. */
85
for (fs = first_analysis_result(); fs != NULL; fs = next_analysis_result())
90
value_string = value_to_readable( fs, FALSE, -1 );
91
fprintf( display_stream, "%d {%s}\n", result_count, value_string );
92
free_mem( &value_string );
96
count_string = int_to_string( result_count );
97
value_string = value_to_readable( fs, FALSE,
98
strlen( count_string ) + 2 );
99
printf( "%s: %s\n", count_string, value_string );
100
free_mem( &value_string );
101
free_mem( &count_string );
105
/* Print analysis results footer. */
108
fprintf( display_stream, "end\n" );
109
fflush( display_stream );
113
/*---------------------------------------------------------------------------*/
117
/* Display analysis tree. */
119
analysis_node_t *node;
120
string_t input, node_type = 0, value_string, surf_string;
122
if (! analysis_has_nodes())
123
complain( "No analysis started." );
124
start_display_process();
125
fprintf( display_stream, "tree\n" );
127
/* Print sentence that has been analysed. */
128
input = new_string_readable( analysis_input, NULL );
129
decode_hangul( &input );
130
fprintf( display_stream, "%s\n", input );
134
for (node = get_first_analysis_node();
136
node = get_next_analysis_node())
138
/* Print node index and type, parent index and rule name. */
141
case INTER_NODE: node_type = "inter"; break;
142
case BREAK_NODE: node_type = "break"; break;
143
case FINAL_NODE: node_type = "final"; break;
144
case UNFINAL_NODE: node_type = "unfinal"; break;
145
case PRUNED_NODE: node_type = "pruned"; break;
147
fprintf( display_stream, "%d %s %d \"%s\" ",
148
node->index, node_type, node->parent_index,
149
SAFE_STRING( node->rule_name ) );
151
/* Print link's surface and feature structure. */
152
if (node->link_surf != NULL)
154
surf_string = new_string_readable( node->link_surf, NULL );
155
decode_hangul( &surf_string );
158
surf_string = new_string( "", NULL );
159
value_string = value_to_readable( node->link_fs, FALSE, -1 );
160
fprintf( display_stream, "{%s} {%s} ", surf_string, value_string );
161
free_mem( &value_string );
162
free_mem( &surf_string );
164
/* Print result surface and feature structure. */
165
if (node->result_surf != NULL)
167
surf_string = new_string_readable( node->result_surf, NULL );
168
decode_hangul( &surf_string );
171
surf_string = new_string( "", NULL );
172
value_string = value_to_readable( node->result_fs, FALSE, -1 );
173
fprintf( display_stream, "{%s} {%s} ", surf_string, value_string );
174
free_mem( &value_string );
175
free_mem( &surf_string );
177
/* Print rule set. */
178
fprintf( display_stream, "\"%s\"\n", SAFE_STRING( node->rule_set ) );
179
free_analysis_node( &node );
181
fprintf( display_stream, "end\n" );
182
fflush( display_stream );
185
/*---------------------------------------------------------------------------*/
188
display_after_analysis( void )
189
/* Display result in the modes that have been switched on after analysis. */
197
/*---------------------------------------------------------------------------*/
200
do_result( string_t arguments )
201
/* Show result of last analysis. */
203
parse_end( &arguments );
204
if (! analysis_has_nodes())
205
complain( "No previous analysis." );
209
static command_t result_command =
211
"result res", do_result,
212
"Show result of last analysis.\n"
216
/*---------------------------------------------------------------------------*/
219
do_tree( string_t arguments )
220
/* Generate analysis tree file and start program to display tree. */
222
parse_end( &arguments );
223
if (! analysis_has_nodes())
224
complain( "No analysis started." );
228
static command_t tree_command =
231
"Display the analysis tree.\n"
233
"In debug mode or after a rule execution error, the tree may be "
237
/* Analysis functions. ======================================================*/
240
analyse_argument( grammar_t grammar, string_t arguments )
241
/* Analyse ARGUMENTS (or last analysis, if *ARGUMENTS == EOS).
242
* Use GRAMMAR (SYNTAX or MORPHOLOGY). */
244
if (*arguments == EOS)
246
if (analysis_input == NULL)
247
complain( "No previous analysis." );
251
free_mem( &analysis_input );
252
analysis_input = new_string( arguments, NULL );
253
preprocess_input( analysis_input, FALSE );
254
encode_hangul( &analysis_input );
257
analyse( grammar, analysis_input, BUILD_TREE, ANALYSE_ALL );
260
/*---------------------------------------------------------------------------*/
263
analyse_line( grammar_t grammar, string_t arguments )
264
/* Analyse a word or a sentence in file FILE, line LINE_NO.
265
* ARGUMENTS must be of format "FILE LINE_NO".
268
int_t line_number, current_line_number;
270
string_t file_name, input_line;
275
/* Read arguments. */
276
file_name = parse_absolute_path( &arguments, NULL );
277
line_number = parse_int( &arguments );
278
parse_end( &arguments );
280
/* Read the line from input. */
281
input_stream = open_stream( file_name, "r" );
282
free_mem( &file_name );
283
current_line_number = 0;
288
free_mem( &input_line );
289
input_line = read_line( input_stream );
290
if (input_line == NULL)
291
complain( "No line %d.", line_number );
292
current_line_number++;
293
} while (current_line_number < line_number);
294
preprocess_input( input_line, FALSE );
295
if (*input_line == EOS)
296
complain( "Line %d is empty.", line_number );
297
free_mem( &analysis_input );
298
analysis_input = input_line;
299
encode_hangul( &analysis_input );
302
close_stream( &input_stream, NULL );
306
analyse( grammar, analysis_input, BUILD_TREE, ANALYSE_ALL );
309
/*---------------------------------------------------------------------------*/
312
do_ma( string_t arguments )
313
/* Analyse ARGUMENTS morphologically. */
315
assert_not_in_debug_mode();
316
set_debug_mode( RUN_MODE, NULL );
317
analyse_argument( MORPHOLOGY, arguments );
318
display_after_analysis();
321
static command_t ma_command =
324
"Analyse the argument morphologically.\n"
326
" ma INPUT -- Analyse INPUT.\n"
327
" ma -- Re-analyse last input.\n"
328
"\"ma\" can't be used in debug mode.\n"
331
/*---------------------------------------------------------------------------*/
334
do_sa( string_t arguments )
335
/* Analyse ARGUMENTS syntactically. */
337
assert_not_in_debug_mode();
338
set_debug_mode( RUN_MODE, NULL );
339
analyse_argument( SYNTAX, arguments );
340
display_after_analysis();
343
static command_t sa_command =
346
"Analyse the argument syntactically.\n"
348
" sa INPUT -- Analyse INPUT.\n"
349
" sa -- Re-analyse last input.\n"
350
"\"sa\" can't be used in debug mode.\n"
353
/*---------------------------------------------------------------------------*/
356
do_ma_line( string_t arguments )
357
/* Analyse ARGUMENTS morphologically. */
359
assert_not_in_debug_mode();
360
set_debug_mode( RUN_MODE, NULL );
361
analyse_line( MORPHOLOGY, arguments );
362
display_after_analysis();
365
static command_t ma_line_command =
367
"ma-line mal", do_ma_line,
368
"Analyse a line in a file morphologically.\n"
370
" ma-line FILE LINE -- Analyse LINE in FILE.\n"
371
"\"ma-line\" can't be used in debug mode.\n"
374
/*---------------------------------------------------------------------------*/
377
do_sa_line( string_t arguments )
378
/* Analyse ARGUMENTS syntactically. */
380
assert_not_in_debug_mode();
381
set_debug_mode( RUN_MODE, NULL );
382
analyse_line( SYNTAX, arguments );
383
display_after_analysis();
386
static command_t sa_line_command =
388
"sa-line sal", do_sa_line,
389
"Analyse a line in a file syntactically.\n"
391
" sa-line FILE LINE -- Analyse LINE in FILE.\n"
392
"\"sa-line\" can't be used in debug mode.\n"
395
/*---------------------------------------------------------------------------*/
397
static void analyse_input( grammar_t grammar, string_t input )
401
string_t string, count, input_readable;
403
analysis_input = new_string( input, NULL );
404
input_readable = new_string_readable( input, NULL );
405
preprocess_input( analysis_input, FALSE );
406
encode_hangul( &analysis_input );
407
analyse( grammar, analysis_input, BUILD_TREE, ANALYSE_ALL );
409
if (analysis_has_results())
411
printf( "Results for %s:\n", input_readable );
413
for (value = first_analysis_result();
415
value = next_analysis_result())
418
count = int_to_string( i );
419
string = value_to_readable( value, FALSE, strlen( count ) + 2) ;
420
printf( "\n%s: %s\n", count, string );
426
printf( "No results for %s.\n", input_readable );
427
free( input_readable );
430
/* Debug support. ===========================================================*/
433
display_where( void )
434
/* Print rule name, left and right surface. */
436
string_t surf, file, rule;
439
source_of_instr( executed_rule_sys, pc, &line, &file, &rule );
440
printf( "At \"%s\", line %d, rule \"%s\", ",
441
name_in_path( file ), line, rule );
443
/* Print state's surface. */
444
surf = get_surface( STATE_SURFACE );
445
decode_hangul( &surf );
446
printf( "surf: %s", surf );
449
/* Print link's surface. */
450
surf = get_surface( LINK_SURFACE );
451
decode_hangul( &surf );
453
printf( ", link: %s", surf );
456
/* Print state number. */
457
if (current_state != -1)
458
printf( ", state: %d", current_state );
460
if (in_emacs_malaga_mode)
461
printf( "SHOW \"%s\":%d:0\n", file, line );
464
/*---------------------------------------------------------------------------*/
467
analysis_node_exists( int_t node_index )
468
/* Return TRUE iff an analysis node with index NODE_INDEX has been
469
* generated in the last analysis. */
471
analysis_node_t *node;
474
for (node = get_first_analysis_node();
476
node = get_next_analysis_node())
479
free_analysis_node( &node );
480
if (index == node_index)
486
/*---------------------------------------------------------------------------*/
489
malaga_debug_state( int_t state, bool_t enter )
490
/* Callback function for "analyse".
491
* This is called with ENTER == TRUE when successor rules for
492
* state with analysis node INDEX will be executed.
493
* It is called with ENTER == FALSE when successor rules for state with
494
* analysis node INDEX have been executed. */
496
if (state != debug_analysis_node_index)
499
set_debug_mode( state_debug_mode, rule_system[ top_grammar ] );
502
state_debug_mode = get_debug_mode();
503
set_debug_mode( RUN_MODE, NULL );
507
/*---------------------------------------------------------------------------*/
510
check_interactive_analysis( void )
512
if (analysis_input == NULL || analysis_input != last_analysis_input)
513
complain( "No interactive analysis." );
516
/*---------------------------------------------------------------------------*/
519
do_debug_state( string_t arguments )
520
/* Analyse the last argument again and stop before executing the rules for a
521
* state whose tree node index is specified in ARGUMENTS. */
523
assert_not_in_debug_mode();
524
check_interactive_analysis();
526
debug_analysis_node_index = parse_int( &arguments );
527
parse_end( &arguments );
529
if (! analysis_node_exists( debug_analysis_node_index ))
530
complain( "State not found." );
532
state_debug_mode = WALK_MODE;
533
debug_state = malaga_debug_state;
534
/* Debug mode is set by "malaga_debug_state" before and after
535
* rule application. */
537
analyse( top_grammar, analysis_input, BUILD_TREE, ANALYSE_ALL );
540
static command_t debug_state_command =
542
"debug-state debug-node dn", do_debug_state,
543
"Re-analyse the last analysis input.\n"
544
"Execute successor rule for given state in debug mode.\n"
545
"Usage: debug-state STATE_INDEX\n"
546
"Analysis is restarted for last input and switches to debug mode\n"
547
"when executing successor rules for state STATE_INDEX.\n"
548
"\"debug-state\" can't be used in debug mode.\n"
551
/*---------------------------------------------------------------------------*/
554
do_debug_ma( string_t arguments )
555
/* Analyse ARGUMENTS morphologically.
556
* Execute morphology combination rules in debug mode. */
558
assert_not_in_debug_mode();
559
set_debug_mode( WALK_MODE, rule_system[ MORPHOLOGY ] );
560
analyse_argument( MORPHOLOGY, arguments );
563
static command_t debug_ma_command =
565
"debug-ma dma debug-mor ma-debug mad", do_debug_ma,
566
"Analyse morphologically. "
567
"Execute morphology combination rules in debug mode.\n"
569
" debug-ma INPUT -- Analyse INPUT.\n"
570
" debug-ma -- Re-analyse the last analysis argument.\n"
571
"Rule execution stops at the first statement.\n"
572
"\"debug-ma\" can't be used in debug mode.\n"
575
/*---------------------------------------------------------------------------*/
578
do_debug_sa( string_t arguments )
579
/* Analyse ARGUMENTS syntactically.
580
* Execute syntax combination rules in debug mode. */
582
assert_not_in_debug_mode();
583
set_debug_mode( WALK_MODE, rule_system[ SYNTAX ] );
584
analyse_argument( SYNTAX, arguments );
587
static command_t debug_sa_command =
589
"debug-sa dsa debug-syn sa-debug sad", do_debug_sa,
590
"Analyse syntactically. Execute syntax combination rules in debug mode.\n"
592
" debug-sa INPUT -- Analyse INPUT.\n"
593
" debug-sa -- Re-analyse the last analysis argument.\n"
594
"Rule execution stops at the first statement.\n"
595
"\"debug-sa\" can't be used in debug mode.\n"
598
/*---------------------------------------------------------------------------*/
601
do_debug_ma_line( string_t arguments )
602
/* Analyse a word in file FILE, line LINE_NO.
603
* ARGUMENTS must be of format "FILE LINE_NO".
604
* Execute morphology combination rules in debug mode. */
606
assert_not_in_debug_mode();
607
set_debug_mode( WALK_MODE, rule_system[ MORPHOLOGY ] );
608
analyse_line( MORPHOLOGY, arguments );
611
static command_t debug_ma_line_command =
613
"debug-ma-line dmal", do_debug_ma_line,
614
"Analyse a line in a file morphologically.\n"
615
"Execute morphology combination rules in debug mode.\n"
617
" debug-ma-line FILE LINE -- Analyse LINE in FILE.\n"
618
"Rule execution stops at the first statement.\n"
619
"\"debug-ma-line\" can't be used in debug mode.\n"
622
/*---------------------------------------------------------------------------*/
625
do_debug_sa_line( string_t arguments )
626
/* Analyse a sentence in file FILE, line LINE_NO.
627
* ARGUMENTS must be of format "FILE LINE_NO".
628
* Execute syntax combination rules in debug mode. */
630
assert_not_in_debug_mode();
631
set_debug_mode( WALK_MODE, rule_system[ SYNTAX ] );
632
analyse_line( SYNTAX, arguments );
635
static command_t debug_sa_line_command =
637
"debug-sa-line dsal", do_debug_sa_line,
638
"Analyse a line in a file syntactically.\n"
639
"Execute syntax combination rules in debug mode.\n"
641
" debug-sa-line FILE LINE_NO -- Analyse LINE_NO in FILE.\n"
642
"Rule execution stops at the first statement.\n"
643
"\"debug-sa-line\" can't be used in debug mode.\n"
646
/* File analysis. ===========================================================*/
649
write_output( string_t input, int_t line_number, string_t error_message,
651
/* Write the result of the last analysis on OUTPUT. */
653
string_t input_string, line_number_string, state_count_string, buffer;
654
string_t value_string, result_number_string;
658
input_string = new_string_readable( input, NULL );
659
decode_hangul( &input_string );
660
line_number_string = int_to_string( line_number );
661
state_count_string = int_to_string( state_count );
662
if (error_message != NULL)
664
/* Print error result. */
665
if (*error_format != EOS)
667
buffer = replace_arguments( error_format, "slne",
668
input_string, line_number_string,
669
state_count_string, error_message );
670
fprintf( output, "%s\n", buffer );
674
else if (! analysis_has_results())
676
/* Print unknown result. */
677
if (*unknown_format != EOS)
679
buffer = replace_arguments( unknown_format, "sln",
680
input_string, line_number_string,
681
state_count_string );
682
fprintf( output, "%s\n", buffer );
691
for (fs = first_analysis_result();
693
fs = next_analysis_result())
698
build_list( result_count );
699
value_string = value_to_readable( value_stack[ --top], FALSE, -1 );
700
buffer = replace_arguments( result_format, "slrfn",
701
input_string, line_number_string,
702
"0", value_string, state_count_string );
703
fprintf( output, "%s\n", buffer );
705
free_mem( &value_string );
709
/* Print real results. */
711
for (fs = first_analysis_result();
713
fs = next_analysis_result())
716
if (*result_format != EOS)
718
result_number_string = int_to_string( result_count );
719
value_string = value_to_readable( fs, FALSE, -1 );
720
buffer = replace_arguments( result_format, "slrfn",
721
input_string, line_number_string,
722
result_number_string, value_string,
723
state_count_string );
724
fprintf( output, "%s\n", buffer );
726
free_mem( &value_string );
727
free_mem( &result_number_string );
732
free_mem( &input_string );
733
free_mem( &line_number_string );
734
free_mem( &state_count_string );
735
if (ferror( output ))
736
complain( "Can't write result: %s.", strerror( errno ) );
739
/*---------------------------------------------------------------------------*/
742
analyse_stream( grammar_t grammar,
746
bool_t expect_quotes )
747
/* Analyse words or sentences in INPUT, write result to OUTPUT.
748
* Use GRAMMAR for analysis, LIST_FILE_NAME is name of INPUT stream.
749
* If EXPECT_QUOTES == TRUE, expect quoted input lines and remove the quotes.
750
* Write statistic information to STATISTICS. */
752
volatile int_t analyses, recognised, results; /* Statistic information. */
753
volatile int_t combi_recognised, robust_recognised, errors, line_number;
754
volatile string_t item, error_message;
755
time_t start_time, stop_time;
757
bool_t old_in_emacs_malaga_mode;
761
item = (grammar == MORPHOLOGY ? "wordform" : "sentence");
762
set_debug_mode( RUN_MODE, NULL );
764
robust_recognised = recognised = results = analyses = errors = 0;
765
combi_recognised = line_number = 0;
766
cache_hits = cache_accesses = 0;
774
free_mem( &input_line );
775
input_line = read_line( input );
776
if (input_line == NULL)
779
preprocess_input( input_line, expect_quotes );
780
if (*input_line != EOS)
782
/* Analyse a non-empty line. */
783
old_in_emacs_malaga_mode = in_emacs_malaga_mode;
784
in_emacs_malaga_mode = FALSE;
785
error_message = NULL;
789
encode_hangul( &input_line );
790
analyse( grammar, input_line, NO_TREE, ANALYSE_ALL );
791
if (recognised_by_combi_rules)
793
if (recognised_by_robust_rule)
795
if (analysis_has_results())
797
for (fs = first_analysis_result();
799
fs = next_analysis_result())
806
error_message = error_text->buffer;
811
in_emacs_malaga_mode = old_in_emacs_malaga_mode;
813
write_output( input_line, line_number, error_message, output );
820
printf( "%s (line %d)\n", error_text->buffer, line_number );
824
free_mem( &input_line );
828
fprintf( statistics, "No %ss analysed.\n", item );
831
time_diff = difftime( stop_time, start_time );
832
fprintf( statistics, "Analysed %ss: %d\n", item, analyses );
833
fprintf( statistics, "Recognised: %d (%.2f%%)\n",
834
recognised, (100.0 * recognised) / analyses );
835
if (combi_recognised > 0)
837
fprintf( statistics, "Recognised by combi rules: %d (%.2f%%)\n",
838
combi_recognised, (100.0 * combi_recognised) / analyses );
840
if (robust_recognised > 0)
842
fprintf( statistics, "Recognised by robust rule: %d (%.2f%%)\n",
843
robust_recognised, (100.0 * robust_recognised) / analyses );
847
fprintf( statistics, "Error-creating %ss: %d (%.2f%%)\n",
848
item, errors, (100.0 * errors) / analyses );
852
fprintf( statistics, "Results per %s: %.4G\n",
853
item, ((double) results / (double) recognised) );
857
fprintf( statistics, "Analysis run time: %d sec\n",
859
fprintf( statistics, "Avg. %ss per second: %d\n",
860
item, (int_t) (analyses / time_diff) );
862
if (cache_accesses > 0)
864
fprintf( statistics, "Cache accesses: %d\n",
866
fprintf( statistics, "Cache hits: %d (%.2f%%)\n",
867
cache_hits, (100.0 * cache_hits) / cache_accesses );
872
/*---------------------------------------------------------------------------*/
875
analyse_file( string_t arguments, grammar_t grammar )
876
/* Open the file with name in ARGUMENTS, which must contain a word list
877
* or sentence list, analyse all its lines according to GRAMMAR,
878
* and write the results to a file with extension ".out". */
880
string_t list_file_name, result_file_name;
881
FILE *input_stream, *output_stream;
883
input_stream = output_stream = NULL;
884
list_file_name = result_file_name = NULL;
887
list_file_name = parse_absolute_path( &arguments, NULL );
888
if (*arguments != EOS)
889
result_file_name = parse_absolute_path( &arguments, NULL );
891
result_file_name = concat_strings( list_file_name, ".out", NULL );
892
parse_end( &arguments );
893
input_stream = open_stream( list_file_name, "r" );
894
output_stream = open_stream( result_file_name, "w" );
895
analyse_stream( grammar, input_stream, output_stream, stdout, FALSE );
899
close_stream( &input_stream, list_file_name );
900
close_stream( &output_stream, result_file_name );
901
free_mem( &list_file_name );
902
free_mem( &result_file_name );
907
/*---------------------------------------------------------------------------*/
910
do_ma_file( string_t arguments )
911
/* Analyse file in ARGUMENTS morphologically. */
913
assert_not_in_debug_mode();
914
analyse_file( arguments, MORPHOLOGY );
917
static command_t ma_file_command =
919
"ma-file maf", do_ma_file,
920
"Analyse a word list file.\n"
921
"Usage: ma-file INPUT_FILE [OUTPUT_FILE]\n"
922
"INPUT_FILE must contain one word form on each line.\n"
923
"The results are written to \"OUTPUT_FILE\".\n"
924
"If OUTPUT_FILE is missing, they are written to \"INPUT_FILE.out\".\n"
925
"\"ma-file\" can't be used in debug mode.\n"
928
/*---------------------------------------------------------------------------*/
931
do_sa_file( string_t arguments )
932
/* Analyse file in ARGUMENTS syntactically. */
934
assert_not_in_debug_mode();
935
if (rule_system[ SYNTAX ] == NULL)
936
complain( "Syntax rule file not loaded." );
937
analyse_file( arguments, SYNTAX );
940
static command_t sa_file_command =
942
"sa-file saf", do_sa_file,
943
"Analyse a sentence list file.\n"
944
"Usage: sa-file INPUT_FILE [OUTPUT_FILE]\n"
945
"INPUT_FILE must contain one sentence on each line.\n"
946
"The results are written to \"OUTPUT_FILE\".\n"
947
"If OUTPUT_FILE is missing, they are written to \"INPUT_FILE.out\".\n"
948
"\"sa-file\" can't be used in debug mode.\n"
951
/*===========================================================================*/
954
do_clear_cache( string_t arguments )
955
/* Clear the wordform analysis cache. */
957
parse_end( &arguments );
961
static command_t clear_cache_command =
963
"clear-cache", do_clear_cache,
964
"Clear the wordform analysis cache.\n"
965
"Usage: clear-cache\n"
968
/*---------------------------------------------------------------------------*/
971
do_info( string_t arguments )
972
/* Show information about morphology and syntax. */
974
parse_end( &arguments );
975
printf( "%s", grammar_info->buffer );
978
static command_t info_command =
981
"Show information about current grammar.\n"
985
/*---------------------------------------------------------------------------*/
987
/* The commands that can be called interactively, in alphabetical order. */
988
static command_t *malaga_commands[] =
990
&backtrace_command, &break_command, &clear_cache_command, &continue_command,
991
&debug_ma_command, &debug_ma_line_command, &debug_sa_command,
992
&debug_sa_line_command, &debug_state_command, &delete_command, &down_command,
993
&finish_command, &frame_command, &get_command, &help_command, &info_command,
994
&list_command, &ma_command, &ma_file_command, &ma_line_command, &mg_command,
995
&next_command, &print_command, &quit_command, &result_command, &run_command,
996
&sa_command, &sa_file_command, &sa_line_command, &set_command, &sg_command,
997
&step_command, &transmit_command, &tree_command, &up_command,
998
&variables_command, &walk_command, &where_command,
1002
/*---------------------------------------------------------------------------*/
1005
main( int argc, char *argv[] )
1006
/* The main function of "malaga". */
1008
enum {INTERACTIVE_MODE, MORPHOLOGY_MODE, SYNTAX_MODE} malaga_mode;
1010
string_t project_file, input;
1011
rule_sys_name_t rule_systems[2]; /* Rule systems for debugger. */
1012
grammar_t grammar; /* Grammar for batch mode. */
1013
bool_t expect_quotes;
1015
expect_quotes = FALSE;
1016
malaga_mode = INTERACTIVE_MODE;
1018
init_basic( "malaga" );
1020
/* Parse arguments. */
1023
if (strcmp_no_case( argv[1], "--version" ) == 0
1024
|| strcmp_no_case( argv[1], "-version" ) == 0
1025
|| strcmp_no_case( argv[1], "-v" ) == 0)
1030
else if (strcmp_no_case( argv[1], "--help" ) == 0
1031
|| strcmp_no_case( argv[1], "-help" ) == 0
1032
|| strcmp_no_case( argv[1], "-h" ) == 0)
1034
printf( "Analyse words and/or sentences according to a Malaga grammar.\n"
1037
"malaga PROJECT-FILE "
1038
"-- Start interactive malaga.\n"
1039
"malaga PROJECT-FILE -m[orphology] "
1040
"-- Run as a morphology filter.\n"
1041
"malaga PROJECT-FILE -s[yntax] "
1042
"-- Run as a syntax filter.\n"
1043
"malaga -v[ersion] "
1044
"-- Print version information.\n"
1046
"-- Print this help.\n\n"
1047
"Option \"-i[nput] STRING\" makes malaga analyse STRING.\n"
1048
"Option \"-q[uoted]\" expects quoted lines in filter mode.\n"
1049
"PROJECT_FILE must end on \".pro\".\n" );
1053
project_file = NULL;
1054
for (i = 1; i < argc; i++)
1056
if (has_extension( argv[i], "pro" ))
1057
set_file_name( &project_file, argv[i] );
1058
else if (strcmp_no_case( argv[i], "-morphology" ) == 0
1059
|| strcmp_no_case( argv[i], "-m" ) == 0)
1061
malaga_mode = MORPHOLOGY_MODE;
1063
else if (strcmp_no_case( argv[i], "-syntax" ) == 0
1064
|| strcmp_no_case( argv[i], "-s" ) == 0)
1066
malaga_mode = SYNTAX_MODE;
1068
else if (strcmp_no_case( argv[i], "-input" ) == 0
1069
|| strcmp_no_case( argv[i], "-i" ) == 0)
1071
if (argv[ ++i ] == NULL)
1072
complain( "Missing string after \"-input\"." );
1074
complain( "Redundant \"-input\"." );
1077
else if (strcmp_no_case( argv[i], "-quoted" ) == 0
1078
|| strcmp_no_case( argv[i], "-q" ) == 0)
1080
expect_quotes = TRUE;
1083
complain( "Illegal argument \"%s\".", argv[i] );
1085
if (project_file == NULL)
1086
complain( "Missing project file name." );
1087
init_malaga( project_file );
1088
if (malaga_mode == INTERACTIVE_MODE)
1091
complain( "Need \"-morphology\" or \"-syntax\"." );
1092
init_debugger( display_where, malaga_commands );
1093
rule_systems[0].rule_sys = rule_system[ MORPHOLOGY ];
1094
rule_systems[0].name = "mor";
1095
rule_systems[1].rule_sys = rule_system[ SYNTAX ];
1096
rule_systems[1].name = "syn";
1097
init_breakpoints( 2, rule_systems );
1100
command_loop( program_name, malaga_commands );
1101
terminate_generation();
1102
terminate_breakpoints();
1103
terminate_debugger();
1107
grammar = (malaga_mode == MORPHOLOGY_MODE) ? MORPHOLOGY : SYNTAX;
1108
if (rule_system[ grammar ] == NULL)
1109
complain( "Rule file not loaded." );
1111
analyse_input( grammar, input );
1113
analyse_stream( grammar, stdin, stdout, stderr, expect_quotes );
1115
stop_display_process();
1117
free_mem( &analysis_input );
1118
free_mem( &project_file );
1123
/* End of file. =============================================================*/