Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Related Pages

command.c

00001 /* 00002 * Copyright (C) 1997-2004 The CDG Team <cdg@nats.informatik.uni-hamburg.de> 00003 * 00004 * This file is free software; as a special exception the author gives 00005 * unlimited permission to copy and/or distribute it, with or without 00006 * modifications, as long as this notice is preserved. 00007 * 00008 * This program is distributed in the hope that it will be useful, but 00009 * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the 00010 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00011 * 00012 * Birth: 3/3/97 00013 */ 00014 00015 /* ------------------------------------------------------------------------- 00016 @addtogroup Command Command - The CDG Scripting Language 00017 @author Ingo Schroeder (see also AUTHORS and THANKS for more) 00018 00019 $Id: command.c,v 1.309 2004/10/04 14:36:12 micha Exp $ 00020 00021 This module implements the \c CDG scripting interface, that is, all the 00022 commands that are available on the \c cdgp prompt or executable via 00023 commandEval(). 00024 00025 Note: do not confuse the scripting interface language with the 00026 constraint grammar language or the language bindings. They are all 00027 separate things. 00028 00029 Each valid \c command corresponds to a C function \c cmdCommand that 00030 implements this command all commands are listed in \ref 00031 interface_commands. Each command is defined by a \ref Command structure, 00032 where the name, the interface completion commands, a little help 00033 message for that command etc are defined. 00034 00035 The following commands exist: 00036 - activate, cmdActivate(): activates a section 00037 - annotation, cmdAnnotation(): prints out one or all annotation 00038 - anno2parse, cmdAnno2Parse(): build a parse from an annotation 00039 and evaluate it 00040 - chunk, cmdChunk(): call a chunk parser on a lattice 00041 - closedb, cmdCloseDB(): closes the database 00042 - compareparses, cmdCompareParses(): compares the structures of two parses 00043 - compile, cmdCompile(): compiles the current grammar 00044 - constraint, cmdConstraint(): prints out one or all constraints 00045 - deactivate, cmdDeactivate(): deactivates a section 00046 - distance, cmdDistance(): prints the distance matrix of a net 00047 - edges, cmdEdges(): prints out one or all edges of a constraint net 00048 - frobbing, cmdFrobbing(): transforms an arbitrary assignment into a solution 00049 - gls, cmdGls(): solve a constraintnet using guided local search 00050 - help, cmdHelp(): gives a short help 00051 - hierarchy, cmdHierarchy(): prints out one or all hierarchies 00052 - hook, cmdHook(): toggle hook-system on or off" 00053 - incrementalcompletion, cmdIncrementalCompletion(): 00054 incremental completion of parses 00055 - inputwordgraph, cmdInputwordgraph(): creates new wordgraph 00056 - isearch, cmdISearch(): incremental parsing of a wordgraph 00057 - level, cmdLevel(): prints out one or all level declarations 00058 - levelsort, cmdLevelsort(): set/check the priority of the defined levels 00059 - lexicon, cmdLexicon(): prints out one or all lexical entries 00060 - license, cmdLicense(): prints out the license 00061 - load, cmdLoad(): loads a file 00062 - ls, cmdLs(): lists one or more files 00063 - net, cmdNet(): prints out one or all constraint net 00064 - netdelete, cmdNetdelete(): deletes a constraint net 00065 - netsearch, cmdNetsearch(): searches a net for globally best solutions 00066 - newnet, cmdNewnet(): builds a new constraint net from a wordgraph 00067 - nonspeccompatible, cmdNonSpecCompatible(): 00068 check compatibility of constraints for incremental parsing 00069 - parsedelete, cmdParsedelete(): deletes a parse 00070 - printparse, cmdPrintParse(): prints the structure of a parse 00071 - printparses, cmdPrintParses(): prints out all parses of a constraint net 00072 - quit, cmdQuit(): quits 00073 - renewnet, cmdRenewnet(): restores a net to pristine state 00074 - reset, cmdReset(): discards all loaded and computed information 00075 - section, cmdSection(): prints out one or all section 00076 - set, cmdSet(): set various system variables 00077 - showlevel, cmdShowlevel(): toggles whether a level is shown or not 00078 - status, cmdStatus(): describes the status of the system 00079 - tagger, cmdTagger(): start/stop POS tagger 00080 - testing, cmdTesting(): undocumented command for testing 00081 - useconstraint, cmdUseconstraint(): 00082 toggles whether a constraint is used or not 00083 - uselevel, cmdUselevel(): toggles whether a level is used or not 00084 - uselexicon, cmdUseLexicon(): 00085 specify which lexicon and which index database to use 00086 - version, cmdVersion(): prints version 00087 - verify, cmdVerify(): compares parse to annotation 00088 - weight, cmdWeight(): changes a constraint's weight 00089 - wordgraph, cmdWordgraph(): prints out one or all wordgraph 00090 - writenet, cmdWriteNet(): writes a TeX representation of the net 00091 - writeparses, cmdWriteParses(): writes XFig and LaTeX files with the parses 00092 - writewordgraph, cmdWriteWordgraph(): writes a wordgraph in an XFig file 00093 @{ 00094 */ 00095 00096 /* ---------------------------------------------------------------------- */ 00097 #include <config.h> 00098 00099 #include <blah.h> 00100 #include <errno.h> 00101 #include <libgen.h> 00102 #include <time.h> 00103 #include <unistd.h> 00104 #include <stdio.h> 00105 #include <string.h> 00106 #include <sys/resource.h> 00107 #include <sys/stat.h> 00108 00109 #ifndef DARWIN 00110 #include "compile.h" 00111 #endif 00112 00113 #include "cdg.h" 00114 #include "chart.h" 00115 #include "chunker.h" 00116 #include "command.h" 00117 #include "constraintnet.h" 00118 #include "eval.h" 00119 #include "frobbing.h" 00120 #include "gls.h" 00121 #include "hook.h" 00122 #include "increment.h" 00123 #include "incrementalcompletion.h" 00124 #include "input.h" 00125 #include "lexemgraph.h" 00126 #include "netsearch.h" 00127 #include "parse.h" 00128 #include "parsing.h" 00129 #include "scache.h" 00130 #include "search.h" 00131 #include "set.h" 00132 #include "shift.h" 00133 #include "statistics.h" 00134 #include "tagger.h" 00135 #include "testing.h" 00136 #include "timer.h" 00137 #include "write.h" 00138 #include "cdgdb.h" 00139 00140 /* -- TYPE DEFINITIONS -------------------------------------------------- */ 00141 00142 /* ------------------------------------------------------------------------- 00143 type of a function that implements a scripting command. 00144 00145 The first parameter \c no is the number of arguments entered by the user 00146 after the command name. The array \c args holds these arguments as a 00147 list of plain strings. For example, the command "\c newnet \c s1" 00148 contains one command and argument. To handle it, the function 00149 cmdNewnet() will be called with two arguments: the number 1 (as we have 00150 one argument) and an array containing the argument strings, which is one 00151 here: "s1". 00152 00153 The job of a CommandFunction() is to check the arguments for consistency 00154 and then either execute the action specified by the command or give reasons 00155 why they are incorrect. 00156 00157 Each command returns 00158 a Boolean which is \ref TRUE on a successful command execution and otherwise 00159 \ref FALSE, that is when an error occurred. 00160 */ 00161 typedef Boolean CommandFunction(int no, char **args); 00162 00163 /* ------------------------------------------------------------------------- 00164 command definition for the \ref interface_commands. 00165 */ 00166 typedef struct { 00167 00168 String name; /**< the name of the command */ 00169 00170 rl_compentry_func_t *args[MAXARGNO]; /**< array of completion functions for each argument */ 00171 00172 CommandFunction *function; /**< function that implements the command */ 00173 00174 Boolean same; /**< completion flag. This is set to 1 for those commands which use the same 00175 * completion-function for all of their arguments */ 00176 00177 String doc; /**< little help text*/ 00178 } Command; 00179 00180 /* -- VARIABLES --------------------------------------------------------- */ 00181 00182 /** \todo Write an explanation of the interface and the completion gadget */ 00183 static int interface_index = 0; 00184 00185 /** \todo Write an explanation of the interface and the completion gadget */ 00186 static int interface_length = 0; 00187 00188 /** \todo Write an explanation of the interface and the completion gadget */ 00189 static List interface_list = NULL; 00190 00191 /** \todo Write an explanation of the interface and the completion gadget */ 00192 static List interface_cell = NULL; 00193 00194 /** \todo Write an explanation of the interface and the completion gadget */ 00195 static HashIterator interface_hashiterator = NULL; 00196 00197 /* ------------------------------------------------------------------------ 00198 flag indicating the end of the command main loop. 00199 Entering the commandLoop() this is set to \ref TRUE. commandLoop() exits 00200 if this global variable is set to FALSE. 00201 */ 00202 static Boolean commandLoopFlag = TRUE; 00203 00204 /* -- FORWARD DECLARATIONS ---------------------------------------------- */ 00205 char **interface_completion(String text, int start, int end); 00206 char *annotation_completion_function(const char *, int); 00207 char *command_completion_function(const char *, int); 00208 char *constraint_completion_function(const char *, int); 00209 char *frob_method_completion_function(const char *, int); 00210 char *hierarchy_completion_function(const char *, int); 00211 char *hook_completion_function(const char *, int); 00212 char *level_completion_function(const char *, int); 00213 char *levelsort_completion_function(const char *, int); 00214 char *lexicon_completion_function(const char *, int); 00215 char *make_rl_string(char *); 00216 char *net_completion_function(const char *, int); 00217 char *parse_completion_function(const char *, int); 00218 char *search_method_completion_function(const char *, int); 00219 char *section_completion_function(const char *, int); 00220 char *set_completion_function(const char *, int); 00221 char *word_completion_function(const char *, int); 00222 char *wordgraph_completion_function(const char *, int); 00223 00224 /* ---------------------------------------------------------------------- 00225 array of all registered wcdg scripting commands. 00226 */ 00227 Command interface_commands[] = { 00228 {"activate", 00229 {section_completion_function}, 00230 cmdActivate, 1, "activates a section"}, 00231 {"annotation", 00232 {annotation_completion_function}, 00233 cmdAnnotation, 0, "prints out one or all annotation"}, 00234 {"anno2parse", 00235 {annotation_completion_function}, 00236 cmdAnno2Parse, 1, "build a parse from an annotation and evaluate it"}, 00237 {"chart", 00238 {wordgraph_completion_function}, 00239 cmdChart, 1, "search for solutions with a chart"}, 00240 {"chunk", 00241 {wordgraph_completion_function}, 00242 cmdChunk, 1, "call a chunk parser on a lattice"}, 00243 {"closedb", 00244 {command_completion_function}, 00245 cmdCloseDB, 1, "close database and write contents to disk"}, 00246 {"compareparses", 00247 {parse_completion_function, parse_completion_function}, 00248 cmdCompareParses, 0, "compares the structures of two parses"}, 00249 {"compile", 00250 {NULL}, 00251 cmdCompile, 0, "compiles the current grammar"}, 00252 {"constraint", 00253 {constraint_completion_function}, 00254 cmdConstraint, 1, "prints out one or all constraints"}, 00255 {"deactivate", 00256 {section_completion_function}, 00257 cmdDeactivate, 1, "deactivates a section"}, 00258 {"distance", 00259 {net_completion_function}, 00260 cmdDistance, 0, "prints the distance matrix of a net"}, 00261 {"edges", 00262 {net_completion_function}, 00263 cmdEdges, 0, "prints out one or all edges of a constraint net"}, 00264 {"frobbing", 00265 {net_completion_function, frob_method_completion_function}, 00266 cmdFrobbing, 0, "transforms an arbitrary assignment into a solution"}, 00267 {"gls", 00268 {net_completion_function}, 00269 cmdGls, 0, "solve a constraintnet using guided local search"}, 00270 {"help", 00271 {command_completion_function}, 00272 cmdHelp, 1, "gives a short help"}, 00273 {"hierarchy", 00274 {hierarchy_completion_function}, 00275 cmdHierarchy, 1, "prints out one or all hierarchies"}, 00276 {"hook", 00277 {hook_completion_function}, 00278 cmdHook, 0, "toggle hook-system on or off"}, 00279 {"incrementalcompletion", 00280 {wordgraph_completion_function}, 00281 cmdIncrementalCompletion, 0, "incremental completion of parses"}, 00282 {"inputwordgraph", 00283 {word_completion_function}, 00284 cmdInputwordgraph, 1, "creates new wordgraph"}, 00285 {"isearch", 00286 {wordgraph_completion_function}, 00287 cmdISearch, 0, "incremental parsing of a wordgraph"}, 00288 {"level", 00289 {level_completion_function}, 00290 cmdLevel, 1, "prints out one or all level declarations"}, 00291 {"levelsort", 00292 {levelsort_completion_function}, 00293 cmdLevelsort, 1, "set/check the priority of the defined levels"}, 00294 {"lexicon", 00295 {lexicon_completion_function}, 00296 cmdLexicon, 1, "prints out one or all lexical entries"}, 00297 {"license", 00298 {NULL}, 00299 cmdLicense, 0, "prints out the license"}, 00300 {"load", 00301 {rl_filename_completion_function}, 00302 cmdLoad, 1, "loads a file"}, 00303 {"ls", 00304 {rl_filename_completion_function}, 00305 cmdLs, 1, "lists one or more files"}, 00306 {"net", 00307 {net_completion_function}, 00308 cmdNet, 1, "prints out one or all constraint net"}, 00309 {"netdelete", 00310 {net_completion_function}, 00311 cmdNetdelete, 1, "deletes a constraint net"}, 00312 {"netsearch", 00313 {net_completion_function, search_method_completion_function}, 00314 cmdNetsearch, 0, "searches a net for globally best solutions"}, 00315 {"newnet", 00316 {wordgraph_completion_function}, 00317 cmdNewnet, 0, "builds a new constraint net from a wordgraph"}, 00318 {"nonspeccompatible", 00319 {constraint_completion_function}, 00320 cmdNonSpecCompatible, 0, 00321 "check compatibility of constraints for incremental parsing"}, 00322 {"parsedelete", 00323 {parse_completion_function}, 00324 cmdParsedelete, 1, "deletes a parse"}, 00325 {"printparse", 00326 {parse_completion_function}, 00327 cmdPrintParse, 0, "prints the structure of a parse"}, 00328 {"printparses", 00329 {net_completion_function}, 00330 cmdPrintParses, 0, "prints out all parses of a constraint net"}, 00331 {"quit", 00332 {NULL}, 00333 cmdQuit, 0, "quits"}, 00334 {"renewnet", 00335 {net_completion_function}, 00336 cmdRenewnet, 0, "restores a net to pristine state"}, 00337 {"reset", 00338 {NULL}, 00339 cmdReset, 0, "discards all loaded and computed information"}, 00340 {"section", 00341 {section_completion_function}, 00342 cmdSection, 0, "prints out one or all section"}, 00343 {"set", 00344 {set_completion_function}, 00345 cmdSet, 0, "set various system variables"}, 00346 {"shift-reduce", 00347 {net_completion_function}, 00348 cmdShift, 0, "builds parse tree as by shift and reduce actions"}, 00349 {"showlevel", 00350 {level_completion_function}, 00351 cmdShowlevel, 1, "toggles whether a level is shown or not"}, 00352 {"status", 00353 {NULL}, 00354 cmdStatus, 0, "describes the status of the system"}, 00355 {"tagger", 00356 {NULL}, 00357 cmdTagger, 0, "start/stop POS tagger"}, 00358 {"testing", 00359 {NULL}, 00360 cmdTesting, 0, "undocumented command for testing"}, 00361 {"useconstraint", 00362 {constraint_completion_function}, 00363 cmdUseconstraint, 1, "toggles whether a constraint is used or not"}, 00364 {"uselevel", 00365 {level_completion_function}, 00366 cmdUselevel, 1, "toggles whether a level is used or not"}, 00367 {"uselexicon", 00368 {rl_filename_completion_function}, 00369 cmdUseLexicon, 0, "specifies lexicon and its index database"}, 00370 {"version", 00371 {NULL}, 00372 cmdVersion, 0, "prints version"}, 00373 {"verify", 00374 {parse_completion_function}, 00375 cmdVerify, 0, "compares parse to annotation"}, 00376 {"weight", 00377 {constraint_completion_function}, 00378 cmdWeight, 1, "changes a constraint's weight"}, 00379 {"wordgraph", 00380 {wordgraph_completion_function}, 00381 cmdWordgraph, 1, "prints out one or all wordgraph"}, 00382 {"writeannotation", 00383 {net_completion_function}, 00384 cmdWriteAnno, 0, "writes best parse of a net to disk as an annotation"}, 00385 {"writenet", 00386 {net_completion_function}, 00387 cmdWriteNet, 0, "writes a TeX representation of the net"}, 00388 {"writeparses", 00389 {net_completion_function}, 00390 cmdWriteParses, 0, "writes XFig and LaTeX files with the parses"}, 00391 {"writewordgraph", 00392 {wordgraph_completion_function}, 00393 cmdWriteWordgraph, 1, "writes a wordgraph in an XFig file"}, 00394 {"parses2prolog", 00395 {NULL}, 00396 cmdParses2prolog, 0, "saves all parses to a file in Prolog format"}, 00397 {"annos2prolog", 00398 {NULL}, 00399 cmdAnnos2prolog, 0, "saves all annotations to a file in Prolog format"}, 00400 00401 /* end of array marker */ 00402 {(char *)NULL, 00403 {NULL}, 00404 NULL, 0, (char *)NULL} 00405 }; 00406 00407 /* ---------------------------------------------------------------------- */ 00408 00409 /* ---------------------------------------------------------------------- 00410 Produce a string suitable for internal processing by readline. 00411 00412 This function serves two purposes: 00413 00414 -# it accepts a string and returns a clone of it. This is necessary 00415 because the readline library insists on doing its own deallocating. 00416 00417 -# if the string passed contains whitespace, it wraps quotes around it 00418 so that the CDG shell will parse it as one string later. That way, 00419 completion works even for identifiers with whitespace in them (highly 00420 discouraged but possible). 00421 00422 TODO: This is not yet quite correct. It can handle identifiers like 00423 "SYN", "um zu", and "it's". But it can fail if a string contains both 00424 whitespace and single quotes: 00425 00426 "Hand me the 'scope, skipper!" 00427 00428 My excuse is that I can think of no reason whatsoever why anybody would 00429 use that sort of identifier in a constraint grammar. 00430 00431 */ 00432 char *make_rl_string(char *s) 00433 { 00434 /* Usually, we just clone the argument. */ 00435 if (strpbrk(s, rl_basic_word_break_characters) == NULL) { 00436 return (strCopy(s)); 00437 } 00438 00439 /* But if the string retrieved has whitespace in it, we wrap quotes around 00440 * it. */ 00441 else { 00442 return strCopy(strPrintf("'%s'", s)); 00443 } 00444 } 00445 00446 /* --------------------------------------------------------------------------- 00447 Compute the completions for commands. 00448 00449 This is one of many functions provided to pass information to the 00450 readline library. These functions all have basically the same structure 00451 which is required by readline: they must return a newly allocated string 00452 every time they are called. They vary only in which strings are returned 00453 as possible completions. 00454 00455 The parameter "text" is the partial string typed by the user so far. The 00456 completion function must now offer the readline library suitable strings 00457 to complete it. This particular function knows what commands the CDG 00458 shell understands, so it iterates over the array interface_commands[] 00459 internally. The other completion functions will iterate over other 00460 structures, obviously. 00461 */ 00462 char *command_completion_function(const char *text, int state) 00463 { 00464 00465 String name; 00466 00467 /* The parameter "state" indicates what state the readline computations are 00468 currently in. state == 0 indicates that this is the first call to this 00469 function during an attempted completion. Therefore we now initialise the 00470 iterator. */ 00471 if (state == 0) { 00472 interface_index = 0; 00473 interface_length = strlen(text); 00474 } 00475 00476 /* Note that this loop will exit the entire function as soon as the first 00477 match is found. Therefore, it may take several calls to this function 00478 until the loop terminates. This coroutine-like behaviour is slightly 00479 weird, but readline absolutely demands it. This is also why we use a 00480 global variable as an iterator. */ 00481 while ((name = interface_commands[interface_index].name) != NULL) { 00482 interface_index++; 00483 00484 /* A match is found if the beginning of the string retrieved from the 00485 internals of CDG matches the partial string typed so far. */ 00486 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00487 return (make_rl_string(name)); 00488 } 00489 } 00490 00491 /* after the loop has terminated, we return NULL to tell the readline 00492 library no further matches will follow. */ 00493 return (NULL); 00494 } 00495 00496 /* ---------------------------------------------------------------------- 00497 Compute completions for constraints. 00498 */ 00499 char *constraint_completion_function(const char *text, int state) 00500 { 00501 String name; 00502 00503 if (state == 0) { 00504 interface_cell = interface_list = 00505 hashListOfKeys(inputCurrentGrammar->constraints); 00506 interface_length = strlen(text); 00507 } 00508 while (interface_cell) { 00509 name = listElement(interface_cell); 00510 interface_cell = listNext(interface_cell); 00511 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00512 return (make_rl_string(name)); 00513 } 00514 } 00515 00516 listDelete(interface_list); 00517 return (NULL); 00518 } 00519 00520 /* ---------------------------------------------------------------------- 00521 Compute completions for the command level. 00522 */ 00523 char *level_completion_function(const char *text, int state) 00524 { 00525 String name; 00526 00527 if (state == 0) { 00528 interface_list = inputCurrentGrammar->levels; 00529 interface_length = strlen(text); 00530 } 00531 while (interface_list != NULL && 00532 (name = ((Level) listElement(interface_list))->id) != NULL) { 00533 interface_list = listNext(interface_list); 00534 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00535 return (make_rl_string(name)); 00536 } 00537 } 00538 return (NULL); 00539 } 00540 00541 /* ---------------------------------------------------------------------- 00542 Compute completions for the command levelsort. 00543 */ 00544 char *levelsort_completion_function(const char *text, int state) 00545 { 00546 String name; 00547 00548 if (state == 0) { 00549 interface_list = inputCurrentGrammar->levels; 00550 interface_length = strlen(text); 00551 } 00552 while (interface_list != NULL && 00553 (name = ((Level) listElement(interface_list))->id) != NULL) { 00554 interface_list = listNext(interface_list); 00555 /* Each argument is only to be used once. Therefore, the following */ 00556 /* line checks if an argument is already in the rl_line_buffer. */ 00557 if (strstr(rl_line_buffer, name)) 00558 continue; 00559 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00560 return (make_rl_string(name)); 00561 } 00562 } 00563 return (NULL); 00564 } 00565 00566 /* ---------------------------------------------------------------------- 00567 Compute completions for lexical entries. 00568 */ 00569 char *lexicon_completion_function(const char *text, int state) 00570 { 00571 String name; 00572 00573 if (state == 0) { 00574 interface_hashiterator = 00575 hashIteratorNew(inputCurrentGrammar->lexicon); 00576 interface_length = strlen(text); 00577 } 00578 00579 while (NULL != (name = (String) hashIteratorNextKey(interface_hashiterator))) { 00580 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00581 return (make_rl_string(name)); 00582 } 00583 } 00584 00585 hashIteratorDelete(interface_hashiterator); 00586 interface_hashiterator = NULL; 00587 return (NULL); 00588 } 00589 00590 /* ---------------------------------------------------------------------- 00591 Compute completions for orthographic words. 00592 */ 00593 char *word_completion_function(const char *text, int state) 00594 { 00595 String name; 00596 String form; 00597 00598 if (state == 0) { 00599 interface_hashiterator = 00600 hashIteratorNew(inputCurrentGrammar->lexicon); 00601 interface_length = strlen(text); 00602 } 00603 00604 while (NULL != (name = (String) hashIteratorNextKey(interface_hashiterator))) { 00605 form = name; 00606 if (interface_length == 0 || strncmp(form, text, interface_length) == 0) { 00607 return (strCopy(form)); 00608 } 00609 } 00610 00611 hashIteratorDelete(interface_hashiterator); 00612 interface_hashiterator = NULL; 00613 return (NULL); 00614 } 00615 00616 00617 /* ---------------------------------------------------------------------- 00618 Compute completions for wordgraphs. 00619 */ 00620 char *wordgraph_completion_function(const char *text, int state) 00621 { 00622 String name; 00623 00624 if (state == 0) { 00625 interface_list = inputCurrentGrammar->lattices; 00626 interface_length = strlen(text); 00627 } 00628 while (interface_list != NULL && 00629 (name = ((Level) listElement(interface_list))->id) != NULL) { 00630 interface_list = listNext(interface_list); 00631 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00632 return (make_rl_string(name)); 00633 } 00634 } 00635 00636 listDelete(interface_list); 00637 return (NULL); 00638 } 00639 00640 /* ---------------------------------------------------------------------- 00641 Compute completions for annotations. 00642 */ 00643 char *annotation_completion_function(const char *text, int state) 00644 { 00645 String name; 00646 00647 if (state == 0) { 00648 interface_cell = interface_list = 00649 hashListOfKeys(inputCurrentGrammar->annotations); 00650 interface_length = strlen(text); 00651 } 00652 00653 while (interface_cell) { 00654 name = listElement(interface_cell); 00655 interface_cell = listNext(interface_cell); 00656 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00657 return (make_rl_string(name)); 00658 } 00659 } 00660 00661 listDelete(interface_list); 00662 return (NULL); 00663 } 00664 00665 /* ---------------------------------------------------------------------- 00666 Compute completions for hierarchies. 00667 */ 00668 char *hierarchy_completion_function(const char *text, int state) 00669 { 00670 String name; 00671 00672 if (state == 0) { 00673 interface_cell = interface_list = 00674 hashListOfKeys(inputCurrentGrammar->hierarchies); 00675 interface_length = strlen(text); 00676 } 00677 00678 while (interface_cell) { 00679 name = listElement(interface_cell); 00680 interface_cell = listNext(interface_cell); 00681 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00682 return (make_rl_string(name)); 00683 } 00684 } 00685 00686 listDelete(interface_list); 00687 return (NULL); 00688 } 00689 00690 /* ---------------------------------------------------------------------- 00691 Compute completions for constraint nets. 00692 */ 00693 char *net_completion_function(const char *text, int state) 00694 { 00695 String name; 00696 00697 if (state == 0) { 00698 interface_cell = interface_list = 00699 hashListOfKeys(cdgNets); 00700 interface_length = strlen(text); 00701 } 00702 00703 while (interface_cell) { 00704 name = listElement(interface_cell); 00705 interface_cell = listNext(interface_cell); 00706 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00707 return (make_rl_string(name)); 00708 } 00709 } 00710 00711 listDelete(interface_list); 00712 return NULL; 00713 } 00714 00715 /* ---------------------------------------------------------------------- 00716 Compute completions for search methods. 00717 */ 00718 char *search_method_completion_function(const char *text, int state) 00719 { 00720 String name; 00721 00722 if (state == 0) { 00723 interface_index = 0; 00724 interface_length = strlen(text); 00725 } 00726 while ((name = search_methods[interface_index].id) != NULL) { 00727 interface_index++; 00728 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00729 return (make_rl_string(name)); 00730 } 00731 } 00732 return (NULL); 00733 } 00734 00735 /* ---------------------------------------------------------------------- 00736 Compute completions for sections. 00737 */ 00738 char *section_completion_function(const char *text, int state) 00739 { 00740 String name; 00741 00742 if (state == 0) { 00743 interface_list = inputSections; 00744 interface_length = strlen(text); 00745 } 00746 while (interface_list != NULL && 00747 (name = ((Section) listElement(interface_list))->id) != NULL) { 00748 interface_list = listNext(interface_list); 00749 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00750 return (make_rl_string(name)); 00751 } 00752 } 00753 return (NULL); 00754 } 00755 00756 /* ---------------------------------------------------------------------- 00757 Compute completions for the set command 00758 */ 00759 char *set_completion_function(const char *text, int state) 00760 { 00761 String name, result = NULL; 00762 List names = setReturnListOfNames(); 00763 Vector options = listToVector(names); 00764 00765 listDelete(names); 00766 00767 if (state == 0) { 00768 interface_length = strlen(text); 00769 interface_index = 0; 00770 } 00771 00772 while (interface_index < vectorSize(options)) { 00773 name = vectorElement(options, interface_index++); 00774 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00775 result = make_rl_string(name); 00776 break; 00777 } 00778 } 00779 00780 vectorDelete(options); 00781 return result; 00782 } 00783 00784 /* ---------------------------------------------------------------------- 00785 Compute completions for frobbing methods. 00786 */ 00787 char *frob_method_completion_function(const char *text, int state) 00788 { 00789 String name; 00790 00791 if (state == 0) { 00792 interface_index = 0; 00793 interface_length = strlen(text); 00794 } 00795 while ((name = frobMethods[interface_index].id) != NULL) { 00796 interface_index++; 00797 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00798 return (make_rl_string(name)); 00799 } 00800 } 00801 00802 return (NULL); 00803 } 00804 00805 /* ---------------------------------------------------------------------- 00806 Compute completions for known hooks. 00807 */ 00808 char *hook_completion_function(const char *text, int state) 00809 { 00810 String name; 00811 00812 if (state == 0) { 00813 interface_index = 0; 00814 interface_length = strlen(text); 00815 } 00816 while (interface_index < vectorSize(hkHooks)) { 00817 name = ((Hook) vectorElement(hkHooks, interface_index))->name; 00818 interface_index++; 00819 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00820 return (make_rl_string(name)); 00821 } 00822 } 00823 00824 return (NULL); 00825 } 00826 00827 /* ---------------------------------------------------------------------- 00828 Compute completions for parses. 00829 */ 00830 char *parse_completion_function(const char *text, int state) 00831 { 00832 String name; 00833 00834 if (state == 0) { 00835 interface_cell = interface_list = 00836 hashListOfKeys(cdgParses); 00837 interface_length = strlen(text); 00838 } 00839 00840 while (interface_cell) { 00841 name = listElement(interface_cell); 00842 interface_cell = listNext(interface_cell); 00843 if (interface_length == 0 || strncmp(name, text, interface_length) == 0) { 00844 return (make_rl_string(name)); 00845 } 00846 } 00847 00848 return (NULL); 00849 } 00850 00851 /* ---------------------------------------------------------------------- 00852 Return a copy of the next command word in S. 00853 00854 Command words are searched in the part of S starting at INDEX and not 00855 exceeding STOP. Command words are separated by instances of the 00856 characters defined in rl_basic_word_break_characters by the readline 00857 library. 00858 */ 00859 String getNextArgument(String s, int *index, int stop) 00860 { 00861 int start; 00862 char buffer[1024]; 00863 int bIndex = 0; 00864 int escaped = 0; 00865 00866 while (s[*index] != '\0' && 00867 s[*index] != '\'' && 00868 strchr(rl_basic_word_break_characters, s[*index]) != NULL && 00869 *index < stop) { 00870 (*index)++; 00871 } 00872 00873 if (*index >= stop || s[*index] == '\0') { 00874 return (NULL); 00875 } 00876 00877 if (s[*index] == '\'') { 00878 (*index)++; 00879 start = *index; 00880 if (s[*index] == '\\') { 00881 escaped = 1; 00882 (*index)++; 00883 } 00884 while (*index < stop && s[*index] != '\0' && !(s[*index] == '\'' && ! escaped)) { 00885 if (s[*index] == '\\' && ! escaped) { 00886 escaped = 1; 00887 (*index)++; 00888 } else { 00889 escaped = 0; 00890 buffer[bIndex++] = s[(*index)++]; 00891 } 00892 } 00893 if (*index >= stop || s[*index] == '\0' || start == *index) 00894 return (NULL); 00895 (*index)++; 00896 if (*index - start > 1000) { 00897 cdgPrintf(CDG_WARNING, "WARNING: argument too long\n"); 00898 return (NULL); 00899 } 00900 /** 00901 (void)strncpy(buffer, &s[start], *index - start - 1); 00902 buffer[*index - start - 1] = '\0'; 00903 **/ 00904 buffer[bIndex] = '\0'; 00905 } else { 00906 start = *index; 00907 while (*index < stop && 00908 s[*index] != '\0' && 00909 strchr(rl_basic_word_break_characters, s[*index]) == NULL) 00910 (*index)++; 00911 if (*index >= stop || start == *index) 00912 return (NULL); 00913 00914 if (*index - start + 1 > 1000) { 00915 cdgPrintf(CDG_WARNING, "WARNING: argument too long\n"); 00916 return (NULL); 00917 } 00918 (void)strncpy(buffer, &s[start], *index - start); 00919 buffer[*index - start] = '\0'; 00920 } 00921 00922 return inputEncodeUmlauts(cdgXCDG ? strDecode(buffer) : buffer); 00923 } 00924 00925 /* ---------------------------------------------------------------------- 00926 Provide context sensitive command completion. 00927 00928 This function is passed to the readline library as the 00929 rl_attempted_completion_function. See the readline documentation for 00930 details of its behaviour. 00931 */ 00932 char **interface_completion(String text, int start, int end) 00933 { 00934 int i, j; 00935 String s, t; 00936 char **matches; 00937 00938 i = 0; 00939 /* get command */ 00940 s = getNextArgument(rl_line_buffer, &i, start); 00941 00942 if (s == NULL) { 00943 /* no argument yet */ 00944 matches = rl_completion_matches(text, command_completion_function); 00945 } else { 00946 /* count args */ 00947 j = 0; 00948 while (NULL != (t = getNextArgument(rl_line_buffer, &i, start))) { 00949 /* hacky */ 00950 cdgFreeString(t); 00951 j++; 00952 } 00953 00954 if (j >= MAXARGNO) { 00955 matches = (char **)NULL; 00956 } else { 00957 /* find command entry */ 00958 i = 0; 00959 while (NULL != (t = interface_commands[i].name) && strcmp(s, t) != 0) { 00960 i++; 00961 } 00962 00963 /* CDG command not found? */ 00964 if (t == NULL) { 00965 matches = (char **)NULL; 00966 } else { 00967 /* is the command one of those which have a fixed number of arguments 00968 * ? */ 00969 /* is there no completion-function-entry for array args, index j ? */ 00970 if (interface_commands[i].args[j] == NULL && 00971 interface_commands[i].same != 1) { 00972 matches = (char **)NULL; 00973 } else { 00974 if (interface_commands[i].same == 1) { 00975 /* this command is of the type which uses the same 00976 completion-function for all arguments */ 00977 matches = 00978 rl_completion_matches(text, interface_commands[i].args[0]); 00979 } else { 00980 /* this command has a fixed number of arguments */ 00981 matches = 00982 rl_completion_matches(text, interface_commands[i].args[j]); 00983 } 00984 } 00985 } 00986 } 00987 00988 cdgFreeString(s); 00989 } 00990 00991 return (matches); 00992 } 00993 00994 /* ---------------------------------------------------------------------- 00995 CDG main event loop. 00996 00997 This function reads and executes commands and terminates 00998 when the \ref commandLoopFlag has been set to \ref FALSE. 00999 \param prompt to be displayed at the command line 01000 \returns the boolean result of the last command, that is \ref TRUE on 01001 success and else \ref FALSE. 01002 */ 01003 Boolean commandLoop(String prompt) 01004 { 01005 String line; 01006 char buffer[MAXBUFFER]; 01007 Boolean useReadline; 01008 Boolean result = TRUE; 01009 01010 useReadline = isatty(fileno(stdin)); 01011 01012 /* completion function */ 01013 rl_attempted_completion_function = (CPPFunction *) interface_completion; 01014 01015 line = NULL; 01016 while (commandLoopFlag) { 01017 /* read from commandline */ 01018 if (useReadline) { 01019 if (line) { 01020 memFree(line); 01021 } 01022 line = readline(prompt); 01023 } else { 01024 /* read from pipe */ 01025 /* 01026 * from manpage of fgets: 01027 * 01028 * RETURN VALUES If end-of-file is encountered and no characters have 01029 * been read, no characters are transferred to s and a null pointer is 01030 * returned. If a read error occurs, such as trying to use these 01031 * functions on a file that has not been opened for read- ing, a null 01032 * pointer is returned and the error indicator for the stream is set. 01033 * If end-of-file is encountered, the EOF indicator for the stream is 01034 * set. Otherwise s is returned. */ 01035 if (!fgets(buffer, MAXBUFFER, stdin)) { 01036 line = NULL; 01037 } else if (strlen(buffer) >= MAXBUFFER - 1) { 01038 cdgPrintf(CDG_WARNING, "WARNING: line too long, skipping\n"); 01039 continue; /* with while(TRUE) */ 01040 } else { 01041 line = buffer; 01042 /* Print line when reading from pipe (like initialization file). */ 01043 cdgPrintf(CDG_DEFAULT, "%s", buffer); 01044 } 01045 } 01046 01047 if (line == NULL) { 01048 /* arguments are not valid or stdin ended */ 01049 cdgPrintf(CDG_DEFAULT, "\n"); 01050 cmdQuit(0, NULL); 01051 } 01052 01053 /* String ``line'' not registered anymore. Free'ing was buggy anyway. */ 01054 result = commandEval(line); 01055 } 01056 if (useReadline && line) { 01057 memFree(line); 01058 } 01059 01060 return result; 01061 } 01062 01063 /* ---------------------------------------------------------------------- 01064 CDG command dispatch routine. 01065 01066 This function interprets one command of the scripting language. 01067 \param line the command line to be evaluated 01068 \returns \ref TRUE on a successful command execution, otherwise \ref FALSE. 01069 */ 01070 Boolean commandEval(String line) 01071 { 01072 int len; 01073 int i = 0, j; 01074 String s, t; 01075 String args[MAXARGNO]; 01076 Boolean result = TRUE; 01077 01078 if (!line) 01079 return TRUE; 01080 01081 len = strlen(line); 01082 /* get command */ 01083 s = getNextArgument(line, &i, len + 1); 01084 01085 if (s == NULL) { 01086 if (len != 0 && strcmp(line, "\n") != 0) 01087 cdgPrintf(CDG_ERROR, "ERROR: Oops, no valid command found\n"); 01088 result = FALSE; 01089 } else if (s[0] == '#' || (s[0] == '/' && s[1] == '/')) { 01090 /* skip comments */ 01091 result = TRUE; 01092 } else { 01093 01094 add_history(line); 01095 01096 for (j = 0; j < MAXARGNO; j++) 01097 args[j] = NULL; 01098 01099 /* get arguments */ 01100 for (j = 0; 01101 j < MAXARGNO && 01102 (args[j] = getNextArgument(line, &i, len + 1)) != NULL; j++) 01103 /* do nothing */ 01104 ; 01105 01106 if (j == MAXARGNO && i < len) { 01107 cdgPrintf(CDG_ERROR, "ERROR: only %d arguments are allowed per line\n", 01108 MAXARGNO); 01109 return FALSE; 01110 } 01111 for (i = 0; 01112 (t = interface_commands[i].name) != NULL && strcmp(s, t) != 0; i++) 01113 /* do nothing */ 01114 ; 01115 01116 if (t == NULL || interface_commands[i].function == NULL) { 01117 cdgPrintf(CDG_ERROR, "ERROR: Oops, command `%s' unknown\n", s); 01118 result = FALSE; 01119 } else { 01120 Boolean tagFlag = FALSE; 01121 01122 /* surround every command by xml tags */ 01123 if (hkVerbosity & CDG_XML) { 01124 writeXmlCommand(line); 01125 tagFlag = TRUE; 01126 } 01127 01128 /* call to command function */ 01129 result = interface_commands[i].function(j, args); 01130 01131 /* close the command tag */ 01132 if (tagFlag && (hkVerbosity & CDG_XML)) { 01133 writeXmlEndTag(); 01134 } 01135 } 01136 01137 cdgFreeString(s); 01138 for (j = 0; j < MAXARGNO && args[j] != NULL; j++) 01139 cdgFreeString(args[j]); 01140 } 01141 cdgFlush(); 01142 01143 return result; 01144 } 01145 01146 /* ---------------------------------------------------------------------- 01147 Leave the command loop. 01148 01149 @see commandLoop 01150 */ 01151 Boolean cmdQuit(int no, char **args) 01152 { 01153 commandLoopFlag = FALSE; 01154 return TRUE; 01155 } 01156 01157 01158 /* ---------------------------------------------------------------------- 01159 List one or more files. 01160 01161 This simply spawns the system command \c ls. 01162 */ 01163 Boolean cmdLs(int no, char **args) 01164 { 01165 String lscmd = "ls -laF"; 01166 int i; 01167 char buffer[1024]; 01168 Boolean result = TRUE; 01169 01170 if (args == NULL) { 01171 cdgPrintf(CDG_ERROR, "cmdLs: ERROR: argument is NULL\n"); 01172 return FALSE; 01173 } 01174 01175 if (no == 0) { 01176 result = (system(lscmd) != -1); 01177 } else { 01178 for (i = 0; i < no && args[i] != NULL; i++) { 01179 /* protection against buffer overflow */ 01180 if (strlen(args[i]) > 512) { 01181 cdgPrintf(CDG_WARNING, 01182 "cmdLs: argument number %d too large, ignoring\n", i); 01183 } else { 01184 sprintf(buffer, "%s %s", lscmd, args[i]); 01185 result = (system(buffer) != -1); 01186 } 01187 } 01188 } 01189 01190 return result; 01191 } 01192 01193 /* ---------------------------------------------------------------------- 01194 Compile current grammar. 01195 01196 Currently broken. 01197 */ 01198 Boolean cmdCompile(int no, char **args) 01199 { 01200 Boolean result = TRUE; 01201 01202 #ifdef DARWIN 01203 cdgPrintf(CDG_ERROR, 01204 "Sorry, the MACOS X version currently doesn't support compiling grammars!\n"); 01205 #else 01206 String sofilename = comCompile(no, args); 01207 01208 if (sofilename) { 01209 Input input = comLoad(sofilename); 01210 01211 if (input) { 01212 cdgPrintf(CDG_INFO, "INFO: hooking compiled constraints\n"); 01213 mergeInput(inputCurrentGrammar, input); 01214 inputCacheInput(inputCurrentGrammar); 01215 } 01216 memFree(input); 01217 evalEvaluationMethod = EMTCompiled; 01218 } else { 01219 result = FALSE; 01220 } 01221 #endif 01222 01223 return result; 01224 } 01225 01226 /* ---------------------------------------------------------------------- 01227 Print the specified constraints. 01228 */ 01229 Boolean cmdConstraint(int no, char **args) 01230 { 01231 Constraint c; 01232 int i; 01233 Boolean result = FALSE; 01234 01235 if (args == NULL) { 01236 cdgPrintf(CDG_ERROR, "cmdConstraint: ERROR: argument is NULL\n"); 01237 return FALSE; 01238 } 01239 01240 for (i = 0; i < no; i++) { 01241 if (NULL != (c = hashGet(inputCurrentGrammar->constraints, args[i]))) { 01242 printConstraint(CDG_DEFAULT, c); 01243 result = TRUE; 01244 } 01245 } 01246 01247 return result; 01248 } 01249 01250 /* ---------------------------------------------------------------------- 01251 Print the specified level declarations. 01252 */ 01253 Boolean cmdLevel(int no, char **args) 01254 { 01255 List l; 01256 Level c; 01257 int i, j, index, noLevels; 01258 Boolean result = FALSE; 01259 01260 if (args == NULL) { 01261 cdgPrintf(CDG_ERROR, "cmdLevel: ERROR: argument is NULL\n"); 01262 return FALSE; 01263 } 01264 01265 /* show all requested levels */ 01266 for (l = inputCurrentGrammar->levels; l; l = listNext(l)) { 01267 c = (Level) listElement(l); 01268 if (no > 0) { 01269 for (i = 0; i < no && args[i] != NULL; i++) { 01270 if (strcmp(c->id, args[i]) == 0) { 01271 printLevel(CDG_DEFAULT, c); 01272 result = TRUE; 01273 break; 01274 } 01275 } 01276 } else { 01277 printLevel(CDG_DEFAULT, c); 01278 result = TRUE; 01279 } 01280 } 01281 01282 if (no > 0) 01283 return result; 01284 01285 cdgPrintf(CDG_DEFAULT, 01286 "\nnumber of binary constraints between values of given levels:\n\n"); 01287 noLevels = listSize(inputCurrentGrammar->levels); 01288 cdgPrintf(CDG_DEFAULT, " |"); 01289 for (i = 0; i < noLevels; i++) 01290 cdgPrintf(CDG_DEFAULT, "%3d ", i); 01291 cdgPrintf(CDG_DEFAULT, "\n"); 01292 cdgPrintf(CDG_DEFAULT, " ----|"); 01293 for (i = 0; i < noLevels; i++) 01294 cdgPrintf(CDG_DEFAULT, "----"); 01295 cdgPrintf(CDG_DEFAULT, "\n"); 01296 for (i = 0; i < noLevels; i++) { 01297 cdgPrintf(CDG_DEFAULT, " %3d |", i); 01298 for (j = 0; j < noLevels; j++) { 01299 index = i * noLevels + j; 01300 cdgPrintf(CDG_DEFAULT, "%3d ", 01301 (int)vectorElement(inputCurrentGrammar->levelMatrixCounter, 01302 index)); 01303 } 01304 cdgPrintf(CDG_DEFAULT, "\n"); 01305 } 01306 01307 c = inputGetMainlevel(inputCurrentGrammar); 01308 if (c) { 01309 cdgPrintf(CDG_DEFAULT, "\n\nMain level is %s\n", c->id); 01310 } 01311 01312 return result; 01313 } 01314 01315 /* ---------------------------------------------------------------------- 01316 Simulate shift-reduce parsing. 01317 */ 01318 Boolean cmdShift(int no, char **args) 01319 { 01320 Boolean result = TRUE; 01321 01322 cdgCtrlCAllowed = TRUE; 01323 cdgCtrlCTrapped = FALSE; 01324 01325 /* set the timelimit for this command */ 01326 if (cdgTimeLimit != 0) { 01327 timerSetAlarm(cdgTimeLimit); 01328 } 01329 01330 result = shift_reduce(no, args); 01331 01332 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01333 01334 /* stop the alarm clock on suspicion */ 01335 timerStopAlarm(); 01336 01337 return result; 01338 } 01339 01340 /* ---------------------------------------------------------------------- 01341 Toggle whether the specified level is shown or not. 01342 */ 01343 Boolean cmdShowlevel(int no, char **args) 01344 { 01345 List l; 01346 Level c; 01347 int i; 01348 Boolean result = FALSE; 01349 01350 if (args == NULL) { 01351 cdgPrintf(CDG_ERROR, "cmdShowlevel: ERROR: argument is NULL\n"); 01352 return FALSE; 01353 } 01354 01355 for (l = inputCurrentGrammar->levels; l; l = listNext(l)) { 01356 c = (Level) listElement(l); 01357 if (no > 0) { 01358 for (i = 0; i < no && args[i] != NULL; i++) { 01359 if (strcmp(c->id, args[i]) == 0) { 01360 c->showflag = !c->showflag; 01361 cdgPrintf(CDG_INFO, "INFO: level `%s' %s shown now\n", 01362 c->id, c->showflag ? "is" : "isn't"); 01363 break; 01364 result = TRUE; 01365 } 01366 } 01367 } else { 01368 c->showflag = !c->showflag; 01369 cdgPrintf(CDG_INFO, "INFO: level `%s' %s shown now\n", 01370 c->id, c->showflag ? "is" : "isn't"); 01371 result = TRUE; 01372 } 01373 } 01374 return result; 01375 } 01376 01377 /* ---------------------------------------------------------------------- 01378 Toggle whether the specified constraint is used or not. 01379 */ 01380 Boolean cmdUseconstraint(int no, char **args) 01381 { 01382 Constraint c; 01383 int i; 01384 Boolean change = FALSE; 01385 01386 if (args == NULL) { 01387 cdgPrintf(CDG_ERROR, "cmdUseconstraint: ERROR: argument is NULL\n"); 01388 return FALSE; 01389 } 01390 01391 for (i = 0; i < no; i++) { 01392 if (NULL != (c = hashGet(inputCurrentGrammar->constraints, args[i]))) { 01393 c->active = !c->active; 01394 change = TRUE; 01395 cdgPrintf(CDG_INFO, "INFO: constraint `%s' %s used now\n", 01396 c->id, c->active ? "is" : "isn't"); 01397 } 01398 } 01399 01400 /* delete all constraint nets */ 01401 if (change) { 01402 cdgDeleteComputed(); 01403 } 01404 01405 return change; 01406 } 01407 01408 /* ---------------------------------------------------------------------- 01409 Toggle whether the specified level is used or not. 01410 */ 01411 Boolean cmdUselevel(int no, char **args) 01412 { 01413 Level c; 01414 int i; 01415 Boolean change = FALSE; 01416 List l; 01417 01418 if (args == NULL) { 01419 cdgPrintf(CDG_ERROR, "cmdUselevel: ERROR: argument is NULL\n"); 01420 return FALSE; 01421 } 01422 01423 for (l = inputCurrentGrammar->levels; l; l = listNext(l)) { 01424 c = (Level) listElement(l); 01425 if (no > 0) { 01426 for (i = 0; i < no && args[i] != NULL; i++) { 01427 if (strcmp(c->id, args[i]) == 0) { 01428 c->useflag = !c->useflag; 01429 change = TRUE; 01430 cdgPrintf(CDG_INFO, "INFO: level `%s' %s used now\n", 01431 c->id, c->useflag ? "is" : "isn't"); 01432 break; 01433 } 01434 } 01435 } else { 01436 c->useflag = !c->useflag; 01437 change = TRUE; 01438 cdgPrintf(CDG_INFO, "INFO: level `%s' %s used now\n", 01439 c->id, c->useflag ? "is" : "isn't"); 01440 } 01441 } 01442 01443 /* delete all constraint nets */ 01444 if (change) { 01445 cdgDeleteComputed(); 01446 } 01447 01448 return change; 01449 } 01450 01451 /* ---------------------------------------------------------------------- 01452 Print the specified lexicon entries. 01453 */ 01454 Boolean cmdLexicon(int no, char **args) 01455 { 01456 List l; 01457 Boolean result = FALSE; 01458 01459 cdgCtrlCAllowed = TRUE; 01460 cdgCtrlCTrapped = FALSE; 01461 01462 if (no == 0) { 01463 HashIterator hi = hashIteratorNew(inputCurrentGrammar->lexicon); 01464 String form; 01465 01466 while (NULL != (form = hashIteratorNextKey(hi))) { 01467 List items = inputLexiconGet(form); 01468 01469 for (l = items; l != NULL; l = listNext(l)) { 01470 printLexiconItem(CDG_DEFAULT, listElement(l)); 01471 cdgPrintf(CDG_INFO, "\n"); 01472 result = TRUE; 01473 } 01474 listForEachDelete(items, freeLexiconItem); 01475 if (cdgCtrlCTrapped) { 01476 break; 01477 } 01478 } 01479 hashIteratorDelete(hi); 01480 01481 } else { 01482 int i; 01483 List l, lexicon; 01484 01485 for (i = 0; i < no; i++) { 01486 lexicon = 01487 inputLexiconGet(args[i]); 01488 for (l = lexicon; l != NULL; l = listNext(l)) { 01489 printLexiconItem(CDG_DEFAULT, listElement(l)); 01490 result = TRUE; 01491 cdgPrintf(CDG_INFO, "\n"); 01492 if (cdgCtrlCTrapped) { 01493 break; 01494 } 01495 } 01496 listForEachDelete(lexicon, freeLexiconItem); 01497 } 01498 } 01499 01500 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01501 01502 return result; 01503 } 01504 01505 /* ---------------------------------------------------------------------- 01506 Print wordgraphs. 01507 */ 01508 Boolean cmdWordgraph(int no, char **args) 01509 { 01510 Lattice lat; 01511 int i; 01512 Boolean result = FALSE; 01513 01514 if (args == NULL) { 01515 cdgPrintf(CDG_ERROR, "cmdWordgraph: ERROR: argument is NULL\n"); 01516 return FALSE; 01517 } 01518 cdgCtrlCAllowed = TRUE; 01519 cdgCtrlCTrapped = FALSE; 01520 01521 if (no == 0) { 01522 List l; 01523 for(l = inputCurrentGrammar->lattices; l != NULL; l = listNext(l)) { 01524 Lattice lat = listElement(l); 01525 printLattice(CDG_DEFAULT, lat); 01526 writeXmlLattice(lat); 01527 result = TRUE; 01528 } 01529 } else { 01530 for (i = 0; i < no && ! cdgCtrlCTrapped; i++) { 01531 if (NULL != (lat = findLattice(args[i]))) { 01532 printLattice(CDG_DEFAULT, lat); 01533 writeXmlLattice(lat); 01534 result = TRUE; 01535 } 01536 } 01537 } 01538 01539 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01540 01541 return result; 01542 } 01543 01544 /* ---------------------------------------------------------------------- 01545 Write the specified wordgraphs to XFig file. 01546 */ 01547 Boolean cmdWriteWordgraph(int no, char **args) 01548 { 01549 List l; 01550 Lattice lat; 01551 Boolean withWeights = FALSE; 01552 Boolean result = FALSE; 01553 01554 if (args == NULL) { 01555 cdgPrintf(CDG_ERROR, "cmdWriteWordgraph: ERROR: argument is NULL\n"); 01556 return FALSE; 01557 } 01558 01559 cdgCtrlCAllowed = TRUE; 01560 cdgCtrlCTrapped = FALSE; 01561 switch (no) { 01562 case 0: 01563 case 1: 01564 cdgPrintf(CDG_ERROR, 01565 "cmdWriteWordgraph: ERROR: writewordgraph wordgraph XFig_filename [-w]\n"); 01566 cdgPrintf(CDG_ERROR, 01567 " -w = writes arc weights;\n"); 01568 cdgPrintf(CDG_ERROR, 01569 " by default, the weights are not written\n"); 01570 result = FALSE; 01571 default: 01572 if (no >= 3 && strcmp(args[2], "-w") == 0) 01573 withWeights = TRUE; 01574 01575 for(l = inputCurrentGrammar->lattices; 01576 l != NULL && !cdgCtrlCTrapped; 01577 l = listNext(l)) { 01578 lat = listElement(l); 01579 if (strcmp(lat->id, args[0]) == 0 || graphContainsWord(lat, args[0])) { 01580 writeLattice(lat, withWeights, args[1]); 01581 result = TRUE; 01582 } 01583 } 01584 } 01585 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01586 01587 return result; 01588 } 01589 01590 /* ---------------------------------------------------------------------- 01591 Print the specified annotation entries. 01592 */ 01593 Boolean cmdAnnotation(int no, char **args) 01594 { 01595 AnnoEntry ae; 01596 int i; 01597 Boolean result = FALSE; 01598 01599 if (args == NULL) { 01600 cdgPrintf(CDG_ERROR, "cmdAnnotation: ERROR: argument is NULL\n"); 01601 abort(); 01602 } 01603 cdgCtrlCAllowed = TRUE; 01604 cdgCtrlCTrapped = FALSE; 01605 01606 if (no == 0) { 01607 HashIterator hi = hashIteratorNew(inputCurrentGrammar->annotations); 01608 while (NULL != (ae = hashIteratorNextValue(hi)) && ! cdgCtrlCTrapped) { 01609 printAnnoEntry(CDG_DEFAULT, ae); 01610 writeXmlAnnoEntry(ae); 01611 result = TRUE; 01612 } 01613 hashIteratorDelete(hi); 01614 } else { 01615 for (i = 0; i < no && ! cdgCtrlCTrapped; i++) { 01616 if (NULL != (ae = findAnnoByName(args[i], TRUE))) { 01617 printAnnoEntry(CDG_DEFAULT, ae); 01618 writeXmlAnnoEntry(ae); 01619 result = TRUE; 01620 } 01621 } 01622 } 01623 01624 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01625 01626 return result; 01627 } 01628 01629 /* ---------------------------------------------------------------------- 01630 Build a parse from an annotation and evaluate it against the current 01631 grammar. 01632 */ 01633 Boolean cmdAnno2Parse(int no, char **args) 01634 { 01635 AnnoEntry ae = NULL; 01636 Parse parse = NULL; 01637 Lattice lattice = NULL; 01638 List annos = NULL; 01639 LexemGraph lg = NULL; 01640 List l; 01641 int i, noParses; 01642 Boolean result = TRUE; 01643 01644 cdgCtrlCAllowed = TRUE; 01645 cdgCtrlCTrapped = FALSE; 01646 01647 /* get the annos which should be converted */ 01648 if (no == 0) { 01649 HashIterator hi = hashIteratorNew(inputCurrentGrammar->annotations); 01650 List l; 01651 Hashtable ht; 01652 01653 while (NULL != (ae = hashIteratorNextValue(hi))) { 01654 annos = listPrependElement(annos, ae); 01655 } 01656 hashIteratorDelete(hi); 01657 01658 if(dbAvailable()) { 01659 01660 /* If all available annotations are to be converted, and lexicon items 01661 need to be autoloaded, then there will probably be a great lot of 01662 them. Therefore it pays to optimize for this case and issue one huge 01663 autoload instead of 12374 individual ones. */ 01664 ht = hashNew(500, 0.8, hashStringHashFunction, hashStringEqualFunction); 01665 01666 for(l = annos; l != NULL; l = listNext(l)) { 01667 AnnoEntry ae = listElement(l); 01668 List m; 01669 for(m = ae->annos; m != NULL; m = listNext(m)) { 01670 Annotation a = listElement(m); 01671 hashSet(ht, a->word, (Pointer)1); 01672 } 01673 } 01674 01675 l = hashListOfKeys(ht); 01676 dbLoadAll(l); 01677 listDelete(l); 01678 hashDelete(ht); 01679 } 01680 } 01681 01682 else { 01683 /* some */ 01684 for (i = 0; i < no && args[i]; i++) { 01685 if ((ae = findAnnoByName(args[i], TRUE))) { 01686 if (!parseFind(ae->id)) { 01687 annos = listPrependElement(annos, ae); 01688 } else { 01689 cdgPrintf(CDG_WARNING, 01690 "WARNING: parse for anno `%s' already exists...skipping\n", 01691 ae->id); 01692 } 01693 } 01694 } 01695 } 01696 01697 /* convert all annos to parses */ 01698 noParses = 0; 01699 for (l = annos; l != NULL; l = listNext(l)) { 01700 ae = listElement(l); 01701 parse = parseFromAnno(ae); 01702 if (!parse) 01703 continue; 01704 01705 /* search lattice for this anno */ 01706 lattice = findLattice(ae->lattice); 01707 if (!lattice) { 01708 cdgPrintf(CDG_WARNING, "WARNING: no lattice for anno `%s'\n", ae->id); 01709 } else if (NULL != 01710 (lg = lgNew(lattice))) { 01711 taggerTag(lg); 01712 if (!parseDecorate(parse, lg, ae)) { 01713 cdgPrintf(CDG_WARNING, 01714 "WARNING: could not decorate parse for annotation `%s'.\n", 01715 ae->id); 01716 } else { 01717 parseEval(parse); 01718 lgDelete(lg); 01719 01720 /* check for word mismatch between annotation and associate lattice */ 01721 if(!latticeBranches(lattice) && 01722 vectorSize(parse->words) != listSize(lattice->arcs)) { 01723 cdgPrintf(CDG_WARNING, 01724 "WARNING: Number of words is not the same in lattice and annotation!\n"); 01725 } 01726 01727 01728 } 01729 } 01730 parseRegister(parse); 01731 noParses++; 01732 01733 if(0 == noParses % 100) { 01734 cdgPrintf(CDG_PROGRESS, 01735 "PROGRESS: generated %d parse%s\n", 01736 noParses, 01737 noParses == 1 ? "" : "s"); 01738 } 01739 01740 if(cdgCtrlCTrapped) { 01741 break; 01742 } 01743 01744 } 01745 01746 if (noParses == 0) { 01747 cdgPrintf(CDG_ERROR, "ERROR: no parses generated \n"); 01748 result = FALSE; 01749 } else { 01750 cdgPrintf(CDG_INFO, 01751 "INFO: generated %d parse%s\n", 01752 noParses, 01753 noParses == 1 ? "" : "s"); 01754 01755 result = TRUE; 01756 } 01757 01758 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01759 01760 if (annos) 01761 listDelete(annos); 01762 01763 return result; 01764 } 01765 01766 /* ---------------------------------------------------------------------- 01767 Print the specified hierarchies. 01768 */ 01769 Boolean cmdHierarchy(int no, char **args) 01770 { 01771 Hierarchy h; 01772 int i; 01773 Boolean result = FALSE; 01774 01775 if (args == NULL) { 01776 cdgPrintf(CDG_ERROR, "cmdHierarchy: ERROR: argument is NULL\n"); 01777 return FALSE; 01778 } 01779 01780 cdgCtrlCAllowed = TRUE; 01781 cdgCtrlCTrapped = FALSE; 01782 01783 for (i = 0; i < no && ! cdgCtrlCTrapped; i++) { 01784 if ((h = hashGet(inputCurrentGrammar->hierarchies, args[i]))) { 01785 printHierarchy(CDG_DEFAULT, h); 01786 /* TODO: writeXmlHierarchy */ 01787 result = TRUE; 01788 } 01789 } 01790 01791 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 01792 01793 return result; 01794 } 01795 01796 /* ---------------------------------------------------------------------- 01797 Print the specified constraint sections. 01798 */ 01799 Boolean cmdSection(int no, char **args) 01800 { 01801 List l; 01802 Section s; 01803 01804 if (args == NULL) { 01805 cdgPrintf(CDG_ERROR, "cmdSection: ERROR: argument is NULL\n"); 01806 return FALSE; 01807 } 01808 for (l = inputSections; l; l = listNext(l)) { 01809 s = (Section) listElement(l); 01810 cdgPrintf(CDG_DEFAULT, "%s, %5d constraint(s), %s\n", 01811 s->active ? " active" : "inactive", s->counter, s->id); 01812 } 01813 01814 return TRUE; 01815 } 01816 01817 /* ---------------------------------------------------------------------- 01818 Set the specified CDG variable. 01819 */ 01820 Boolean cmdSet(int no, char **args) 01821 { 01822 String p, v; 01823 01824 if (args == NULL) { 01825 cdgPrintf(CDG_ERROR, "cmdSet: ERROR: argument is NULL\n"); 01826 return FALSE; 01827 } 01828 01829 if (no == 1) { 01830 return setPrint(CDG_INFO, args[0]); 01831 } 01832 01833 if (no == 2) { 01834 p = args[0]; 01835 v = args[1]; 01836 return setValue(p, v); 01837 } 01838 01839 cdgPrintf(CDG_ERROR, 01840 "ERROR: `set' expects one or two arguments, but got %d\n", no); 01841 01842 return FALSE; 01843 } 01844 01845 /* ---------------------------------------------------------------------- 01846 Deactivate constraint classes. 01847 01848 All constraint classes that are named as arguments are deactivated, that 01849 is, their field ->active is set to FALSE. The effect is that these 01850 constraints are not used for evaluation, as if they had never been 01851 defined. Since this changes the basis of evaluation, this is treated 01852 like a change in the grammar, i.e. all previously computed structures 01853 become invalid and are deleted. 01854 */ 01855 Boolean cmdDeactivate(int no, char **args) 01856 { 01857 Section s; 01858 int i; 01859 Boolean change = FALSE; 01860 01861 if (0 == no) { 01862 List l; 01863 change = TRUE; 01864 for(l = inputSections; l != NULL; l = listNext(l)) { 01865 s = listElement(l); 01866 s->active = FALSE; 01867 } 01868 } 01869 01870 for (i = 0; i < no && args[i] != NULL; i++) { 01871 if (NULL != (s = findSection(args[i]))) { 01872 change = TRUE; 01873 s->active = FALSE; 01874 } 01875 } 01876 01877 /* delete all constraint nets */ 01878 if (change) { 01879 cdgDeleteComputed(); 01880 } 01881 01882 return change; 01883 } 01884 01885 /* ---------------------------------------------------------------------- 01886 Activate constraint classes. 01887 01888 All constraint classes that are named as arguments are activated, that 01889 is, their field ->active is set to TRUE. The effect is that these 01890 constraints are used (again) for evaluation. Since this changes the 01891 basis of evaluation, this is treated like a change in the grammar, i.e. 01892 all previously computed structures become invalid and are deleted. 01893 */ 01894 Boolean cmdActivate(int no, char **args) 01895 { 01896 Section s; 01897 int i; 01898 Boolean change = FALSE; 01899 01900 if (0 == no) { 01901 List l; 01902 change = TRUE; 01903 for(l = inputSections; l != NULL; l = listNext(l)) { 01904 s = listElement(l); 01905 s->active = TRUE; 01906 } 01907 } 01908 01909 for (i = 0; i < no && args[i] != NULL; i++) { 01910 if (NULL != (s = findSection(args[i]))) { 01911 change = TRUE; 01912 s->active = TRUE; 01913 } 01914 } 01915 /* delete all constraint nets */ 01916 if (change) { 01917 cdgDeleteComputed(); 01918 } 01919 01920 return change; 01921 } 01922 01923 /* ---------------------------------------------------------------------- 01924 Compare the specified parses. 01925 */ 01926 Boolean cmdCompareParses(int no, char **args) 01927 { 01928 Parse p1 = NULL; 01929 Parse p2 = NULL; 01930 ParseCmpStatStruct stat; 01931 Boolean result = TRUE; 01932 01933 if (args == NULL) { 01934 cdgPrintf(CDG_ERROR, "cmdCompareParses: ERROR: argument is NULL\n"); 01935 return FALSE; 01936 } 01937 01938 if (0 == no || no > 2) { 01939 cdgPrintf(CDG_ERROR, 01940 "ERROR: `compareparses' needs two parses: a reference and a test\n"); 01941 return FALSE; 01942 } 01943 01944 cdgCtrlCAllowed = TRUE; 01945 cdgCtrlCTrapped = FALSE; 01946 01947 p1 = hashGet(cdgParses, args[0]); 01948 p2 = hashGet(cdgParses, args[1]); 01949 if (no == 1) { 01950 p2 = parseMostRecentlyCreatedParse; 01951 } 01952 01953 if (p1 == NULL) { 01954 cdgPrintf(CDG_ERROR, "ERROR: can't find a parse `%s'\n", args[0]); 01955 return FALSE; 01956 } 01957 if (p2 == NULL) { 01958 if (no == 2) { 01959 cdgPrintf(CDG_ERROR, "ERROR: can't find a parse `%s'\n", args[1]); 01960 } else { 01961 cdgPrintf(CDG_ERROR, "ERROR: can't find a recent parse\n"); 01962 } 01963 return FALSE; 01964 } 01965 01966 result = (parseCompare(p1, p2, &stat, PC_ALL, PC_STRICT) >= 0); 01967 writeXmlParseComparison(p1, p2, &stat); 01968 01969 return result; 01970 } 01971 01972 /* ---------------------------------------------------------------------- 01973 Prints the specified Parse on stdout. 01974 */ 01975 Boolean cmdPrintParse(int no, char **args) 01976 { 01977 Parse p = NULL; 01978 AnnoEntry anno = NULL; 01979 01980 if (args == NULL) { 01981 cdgPrintf(CDG_ERROR, "cmdPrintParse: ERROR: argument is NULL\n"); 01982 return FALSE; 01983 } 01984 01985 cdgCtrlCAllowed = TRUE; 01986 cdgCtrlCTrapped = FALSE; 01987 if (no == 1) { 01988 p = hashGet(cdgParses, args[0]); 01989 if (p == NULL) { 01990 cdgPrintf(CDG_ERROR, "ERROR: can't find a parse `%s'\n", args[0]); 01991 return FALSE; 01992 } 01993 } else if (no == 0) { 01994 p = parseMostRecentlyCreatedParse; 01995 if (p == NULL) { 01996 cdgPrintf(CDG_ERROR, "ERROR: can't find a recent parse\n"); 01997 return FALSE; 01998 } 01999 } else { 02000 cdgPrintf(CDG_ERROR, "ERROR: `printparse' needs one parse\n"); 02001 return FALSE; 02002 } 02003 02004 parsePrint(p); 02005 writeXmlParse(p); 02006 02007 /* write extra annotation info */ 02008 anno = parse2annotation(p); 02009 if (anno) { /* for sure */ 02010 writeXmlAnnoEntry(anno); 02011 freeAnnoEntry(anno); 02012 return TRUE; 02013 } 02014 02015 return FALSE; 02016 } 02017 02018 /* ---------------------------------------------------------------------- 02019 Print the specified constraint net. 02020 */ 02021 Boolean cmdNet(int no, char **args) 02022 { 02023 int i; 02024 ConstraintNet net = NULL; 02025 02026 if (args == NULL) { 02027 cdgPrintf(CDG_ERROR, "cmdNet: ERROR: argument is NULL\n"); 02028 return FALSE; 02029 } 02030 02031 cdgCtrlCAllowed = TRUE; 02032 cdgCtrlCTrapped = FALSE; 02033 if (no > 0) { 02034 for (i = 0; i < no && args[i] != NULL && !cdgCtrlCTrapped; i++) { 02035 net = hashGet(cdgNets, args[i]); 02036 if (!net) { 02037 cdgPrintf(CDG_ERROR, "ERROR: can't find a net `%s'\n", args[i]); 02038 return FALSE; 02039 } 02040 } 02041 } else { 02042 if (cnMostRecentlyCreatedNet != NULL) { 02043 net = cnMostRecentlyCreatedNet; 02044 } 02045 } 02046 02047 if (net) { 02048 cnPrint(CDG_DEFAULT, net); 02049 return TRUE; 02050 } else { 02051 cdgPrintf(CDG_ERROR, 02052 "ERROR: `net' needs a constraint net id or a default net\n"); 02053 return FALSE; 02054 } 02055 } 02056 02057 /* ---------------------------------------------------------------------- 02058 Adjust the weight of a constraint. 02059 */ 02060 Boolean cmdWeight(int no, char **args) 02061 { 02062 Number x; 02063 HashIterator hi; 02064 Constraint c; 02065 static char *usage = "usage: weight [<constraint> [[absolute] <weight>]]\n"; 02066 02067 switch (no) { 02068 case 0: 02069 hi = hashIteratorNew(inputCurrentGrammar->constraints); 02070 while ((c = hashIteratorNextValue(hi))) { 02071 cdgPrintf(CDG_INFO, "%s: %7.5f\n", c->id, inputGetWeight(c)); 02072 } 02073 hashIteratorDelete(hi); 02074 break; 02075 02076 case 1: 02077 if ((c = hashGet(inputCurrentGrammar->constraints, args[0]))) { 02078 cdgPrintf(CDG_INFO, "%s: %4.3e\n", c->id, inputGetWeight(c)); 02079 } 02080 break; 02081 02082 case 2: 02083 if ((c = hashGet(inputCurrentGrammar->constraints, args[0]))) { 02084 if (!sscanf(args[1], "%lf", &x)) { 02085 cdgPrintf(CDG_ERROR, "ERROR: can't read weight `%s'\n", args[1]); 02086 return FALSE; 02087 } 02088 inputSetWeight(c, x, FALSE); 02089 } 02090 break; 02091 case 3: 02092 if ((c = hashGet(inputCurrentGrammar->constraints, args[0]))) { 02093 if (strcmp(args[1], "absolute")) { 02094 cdgPrintf(CDG_ERROR, usage); 02095 return FALSE; 02096 } 02097 if (!sscanf(args[2], "%lf", &x)) { 02098 cdgPrintf(CDG_ERROR, "ERROR: can't read weight `%s'\n", args[2]); 02099 return FALSE; 02100 } 02101 inputSetWeight(c, x, TRUE); 02102 } 02103 break; 02104 default: 02105 cdgPrintf(CDG_ERROR, usage); 02106 return FALSE; 02107 } 02108 02109 return TRUE; 02110 } 02111 02112 /* ---------------------------------------------------------------------- 02113 Perform a complete search for globally best solution. 02114 */ 02115 Boolean cmdNetsearch(int no, char **args) 02116 { 02117 ConstraintNet net; 02118 Boolean result; 02119 02120 if (args == NULL) { 02121 cdgPrintf(CDG_ERROR, "cmdNetsearch: ERROR: argument is NULL\n"); 02122 return FALSE; 02123 } 02124 02125 if (no < 1 || args[0] == NULL) { 02126 if (cnMostRecentlyCreatedNet == NULL) { 02127 cdgPrintf(CDG_ERROR, 02128 "ERROR: `netsearch' needs a constraint net id or a default net\n"); 02129 return FALSE; 02130 } 02131 net = cnMostRecentlyCreatedNet; 02132 no = 0; 02133 args = NULL; 02134 cdgPrintf(CDG_INFO, 02135 "INFO: using most recently created net `%s'\n", net->id); 02136 02137 } else { 02138 net = hashGet(cdgNets, args[0]); 02139 if (!net) { 02140 cdgPrintf(CDG_ERROR, 02141 "ERROR: `netsearch': constraint net `%s' unknown\n", args[0]); 02142 return FALSE; 02143 } 02144 no--; 02145 args = &args[1]; 02146 } 02147 02148 cdgCtrlCAllowed = TRUE; 02149 cdgCtrlCTrapped = FALSE; 02150 result = (netsearch(net, no, args) >= 0); 02151 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 02152 02153 /* print solution(s) */ 02154 if (hkVerbosity & CDG_SEARCHRESULT) { 02155 cnPrintParses(net); 02156 } 02157 cnPrintInfo(net); 02158 02159 writeXmlParses(net->parses); 02160 writeXmlNetInfo(net); 02161 02162 return result; 02163 } 02164 02165 /* ---------------------------------------------------------------------- 02166 Start or stop the tagger. 02167 */ 02168 Boolean cmdTagger(int no, char **args) 02169 { 02170 02171 if(1 != no) { 02172 cdgPrintf(CDG_ERROR, "ERROR: please use `tagger on' of `tagger off'.\n"); 02173 return FALSE; 02174 } 02175 02176 if(!strcmp("on", args[0]) && !taggerUp()) { 02177 taggerStartStop(); 02178 } 02179 if(!strcmp("off", args[0]) && taggerUp()) { 02180 taggerStartStop(); 02181 } 02182 return TRUE; 02183 02184 } 02185 02186 /* ---------------------------------------------------------------------- 02187 Undocumented command for testing 02188 mode=1: determine base line for accuracy 02189 mode=2: determine base line for accuracy (TODO: is that correct??) 02190 mode=3: compare two lexica bit for bit 02191 mode=4: approve compiled grammar 02192 */ 02193 Boolean cmdTesting(int no, char **args) 02194 { 02195 int mode; 02196 Boolean result = TRUE; 02197 02198 if (no <= 0 || !args[0]) { 02199 cdgPrintf(CDG_ERROR, "ERROR: wrong number of arguments\n"); 02200 return FALSE; 02201 } 02202 if (!sscanf(args[0], "%d", &mode)) { 02203 cdgPrintf(CDG_ERROR, "ERROR: cannot determine testing mode\n"); 02204 return FALSE; 02205 } 02206 02207 switch (mode) { 02208 case 1: 02209 tst1(no - 1, &args[1]); 02210 break; 02211 case 2: 02212 tst2(no - 1, &args[1]); 02213 break; 02214 case 3: 02215 tst3(no - 1, &args[1]); 02216 break; 02217 #ifndef DARWIN 02218 case 4: 02219 comApprove(no - 1, &args[1]); 02220 break; 02221 #endif 02222 case 5: 02223 tst5(no - 1, &args[1]); 02224 break; 02225 case 7: 02226 tst7(no - 1, &args[1]); 02227 break; 02228 default: 02229 cdgPrintf(CDG_ERROR, "ERROR: Which test do you want? Mode %d unknown\n", 02230 mode); 02231 result = FALSE; 02232 break; 02233 } 02234 02235 return result; 02236 } 02237 02238 /* ---------------------------------------------------------------------- 02239 Try to find a complete solution by transformation. 02240 */ 02241 Boolean cmdFrobbing(int no, char **args) 02242 { 02243 Boolean result = TRUE; 02244 02245 cdgCtrlCAllowed = TRUE; 02246 cdgCtrlCTrapped = FALSE; 02247 02248 /* set the timelimit for this command */ 02249 if (cdgTimeLimit != 0) { 02250 timerSetAlarm(cdgTimeLimit); 02251 } 02252 02253 result = frobbing(no, args); 02254 02255 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 02256 02257 /* stop the alarm clock on suspicion */ 02258 timerStopAlarm(); 02259 02260 return result; 02261 } 02262 02263 /* ---------------------------------------------------------------------- 02264 Print parses of the specified net. 02265 */ 02266 Boolean cmdPrintParses(int no, char **args) 02267 { 02268 ConstraintNet net = NULL; 02269 int i; 02270 02271 if (args == NULL) { 02272 cdgPrintf(CDG_ERROR, "cmdPrintParses: ERROR: argument is NULL\n"); 02273 return FALSE; 02274 } 02275 if (no > 0) { 02276 for (i = 0; i < no && args[i] != NULL; i++) { 02277 ConstraintNet net = cnFindNet(args[i]); 02278 if (!net) { 02279 return FALSE; 02280 } 02281 } 02282 } else if (cnMostRecentlyCreatedNet != NULL) { 02283 net = cnMostRecentlyCreatedNet; 02284 } else { 02285 cdgPrintf(CDG_ERROR, 02286 "ERROR: `printparses' needs a constraint net id or a default net\n"); 02287 return FALSE; 02288 } 02289 02290 cdgCtrlCAllowed = TRUE; 02291 cdgCtrlCTrapped = FALSE; 02292 02293 cnPrintParses(net); 02294 writeXmlParses(net->parses); 02295 02296 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 02297 cnPrintInfo(net); 02298 02299 return TRUE; 02300 } 02301 02302 /* ---------------------------------------------------------------------- 02303 Delete the specified parse. 02304 */ 02305 Boolean cmdParsedelete(int no, char **args) 02306 { 02307 Boolean force = FALSE; 02308 String wordgraph = NULL; 02309 Parse p = NULL; 02310 List l, m; 02311 int i = 0; 02312 int n = 0; 02313 String usage = "Usage: parsedelete parse1 parse2 ...\n" 02314 " parsedelete -w wordgraph [-f]\n"; 02315 02316 /* no arguments on the command line */ 02317 if (no == 0) { 02318 l = hashListOfKeys(cdgParses); 02319 for(m = l; m != NULL; m = listNext(m)) { 02320 String id = listElement(m); 02321 Parse p = hashRemove(cdgParses, id); 02322 parseDelete(p); 02323 } 02324 listDelete(m); 02325 return TRUE; 02326 } 02327 02328 if (strcmp(args[0], "-w") == 0) { 02329 02330 /* use the wordgraph variant */ 02331 if (no != 2) { 02332 cdgPrintf(CDG_ERROR, usage); 02333 return FALSE; 02334 } 02335 if (no == 3 && strcmp(args[2], "-f") == 0) { 02336 force = TRUE; 02337 } 02338 wordgraph = strRegister(args[1]); 02339 02340 for(l = m = hashListOfKeys(cdgParses); 02341 l != NULL; l = listNext(l)) { 02342 p = hashGet(cdgParses, listElement(l)); 02343 if (!p->latticeId || p->latticeId != wordgraph) { 02344 continue; 02345 } 02346 02347 /* keep parses made from annos */ 02348 if (p->searchStrategy != NULL && 02349 strcmp(p->searchStrategy, "anno2parse") == 0) { 02350 if (force) { 02351 cdgPrintf(CDG_INFO, "INFO: forcing deletion of `%s'\n", p->id); 02352 } else { 02353 continue; 02354 } 02355 } 02356 hashRemove(cdgParses, listElement(l)); 02357 parseDelete(p); 02358 n++; 02359 if (parseMostRecentlyCreatedParse == p) { 02360 parseMostRecentlyCreatedParse = NULL; 02361 } 02362 } 02363 } else { 02364 02365 /* use the parse list */ 02366 for (i = 0; i < no && args[i]; i++) { 02367 Parse p = hashGet(cdgParses, args[i]); 02368 if(p) { 02369 hashRemove(cdgParses, args[i]); 02370 parseDelete(p); 02371 n++; 02372 if (parseMostRecentlyCreatedParse == p) { 02373 parseMostRecentlyCreatedParse = NULL; 02374 } 02375 } 02376 } 02377 } 02378 cdgPrintf(CDG_INFO, "INFO: deleted %d parse(s)\n", n); 02379 02380 return (n > 0); 02381 } 02382 02383 /* ---------------------------------------------------------------------- 02384 Delete constraint nets. 02385 02386 If no argument is given, delete all known constraint nets. 02387 Otherwise, delete all named nets. 02388 */ 02389 Boolean cmdNetdelete(int no, char **args) 02390 { 02391 int i; 02392 02393 if (args == NULL) { 02394 cdgPrintf(CDG_ERROR, "cmdNetdelete: ERROR: argument is NULL\n"); 02395 return FALSE; 02396 } 02397 02398 if(0 == no) { 02399 02400 /* delete all nets */ 02401 List l, m; 02402 l = hashListOfKeys(cdgNets); 02403 for(m = l; m != NULL; m = listNext(m)) { 02404 String id = listElement(m); 02405 ConstraintNet net = hashRemove(cdgNets, id); 02406 cnDelete(net); 02407 } 02408 listDelete(m); 02409 cnMostRecentlyCreatedNet = NULL; 02410 02411 l = hashListOfKeys(cdgProblems); 02412 for(m = l; m != NULL; m = listNext(m)) { 02413 String id = listElement(m); 02414 Problem P = hashRemove(cdgProblems, id); 02415 deleteProblem(P); 02416 } 02417 listDelete(m); 02418 02419 } else { 02420 for (i = 0; i < no && args[i] != NULL; i++) { 02421 ConstraintNet net = hashGet(cdgNets, args[i]); 02422 if (!net) { 02423 cdgPrintf(CDG_ERROR, "ERROR: can't find a net `%s'\n", args[i]); 02424 return FALSE; 02425 } 02426 if(net == cnMostRecentlyCreatedNet) { 02427 cnMostRecentlyCreatedNet = NULL; 02428 } 02429 cnDelete(net); 02430 hashRemove(cdgNets, args[i]); 02431 } 02432 } 02433 02434 return FALSE; 02435 } 02436 02437 /* ---------------------------------------------------------------------- 02438 Print edges of the specified constraint net. 02439 */ 02440 Boolean cmdEdges(int no, char **args) 02441 { 02442 int i; 02443 ConstraintNet net = NULL; 02444 ConstraintEdge e; 02445 ConstraintNode start = NULL; 02446 ConstraintNode stop = NULL; 02447 02448 if (args == NULL) { 02449 cdgPrintf(CDG_ERROR, "cmdEdges: ERROR: argument is NULL\n"); 02450 return FALSE; 02451 } 02452 if (no < 1 || no > 3) { 02453 cdgPrintf(CDG_ERROR, 02454 "ERROR: `edges' needs a net id and optionally two node indices\n"); 02455 return FALSE; 02456 } 02457 02458 net = hashGet(cdgNets, args[0]); 02459 if (!net) { 02460 cdgPrintf(CDG_ERROR, 02461 "ERROR: `edges': no such constraint net `%s'\n", args[0]); 02462 return FALSE; 02463 } 02464 02465 if (!net->edges) { 02466 cdgPrintf(CDG_ERROR, "ERROR: no edges were built for net `%s'\n", net->id); 02467 return FALSE; 02468 } 02469 02470 if (no > 1 && args[1] != NULL) { 02471 sscanf(args[1], "%d", &i); 02472 if (i < 0 || i > vectorSize(net->nodes) - 1) { 02473 cdgPrintf(CDG_ERROR, "ERROR: invalid start index `%d'\n", i); 02474 return FALSE; 02475 } 02476 start = (ConstraintNode) vectorElement(net->nodes, i); 02477 } 02478 if (no > 2 && args[2] != NULL) { 02479 sscanf(args[2], "%d", &i); 02480 if (i < 0 || i > vectorSize(net->nodes) - 1) { 02481 cdgPrintf(CDG_ERROR, "ERROR: invalid stop index `%d'\n", i); 02482 return FALSE; 02483 } 02484 stop = (ConstraintNode) vectorElement(net->nodes, i); 02485 } 02486 for (i = 0; i < vectorSize(net->edges); i++) { 02487 e = (ConstraintEdge) vectorElement(net->edges, i); 02488 if ((start == NULL || e->start == start) 02489 && (stop == NULL || e->stop == stop)) 02490 cnPrintEdge(CDG_DEFAULT, e); 02491 } 02492 02493 return TRUE; 02494 } 02495 02496 /* ---------------------------------------------------------------------- 02497 Write the specified constraint net to an XFig file. 02498 */ 02499 Boolean cmdWriteNet(int no, char **args) 02500 { 02501 ConstraintNet net; 02502 02503 if (args == NULL) { 02504 cdgPrintf(CDG_ERROR, "cmdWriteNet: ERROR: argument is NULL\n"); 02505 return FALSE; 02506 } 02507 02508 cdgCtrlCAllowed = TRUE; 02509 cdgCtrlCTrapped = FALSE; 02510 02511 switch (no) { 02512 case 0: 02513 cdgPrintf(CDG_ERROR, 02514 "cmdWritenet: ERROR: writenet [net] LaTeX_filename\n"); 02515 return FALSE; 02516 case 1: 02517 if (cnMostRecentlyCreatedNet != NULL) 02518 writeConstraintNet(cnMostRecentlyCreatedNet, args[0]); 02519 else 02520 cdgPrintf(CDG_ERROR, 02521 "ERROR: `writenet' needs a constraint net id or a default net\n"); 02522 return FALSE; 02523 break; 02524 default: 02525 net = hashGet(cdgNets, args[0]); 02526 if(net) { 02527 writeConstraintNet(net, args[1]); 02528 } else { 02529 cdgPrintf(CDG_ERROR, "ERROR: cannot find a net '%s'\n", args[0]); 02530 return FALSE; 02531 } 02532 } 02533 02534 return TRUE; 02535 } 02536 02537 /* ---------------------------------------------------------------------- 02538 Write best Parse of a net to disk as an annotation. 02539 */ 02540 Boolean cmdWriteAnno(int no, char **args) { 02541 ConstraintNet net; 02542 Parse best = NULL; 02543 List l; 02544 AnnoEntry ae; 02545 02546 if(0 == no) { 02547 if(cnMostRecentlyCreatedNet) { 02548 net = cnMostRecentlyCreatedNet; 02549 } else { 02550 cdgPrintf(CDG_ERROR, 02551 "ERROR: `writeannotation' needs a constraint net id or a default net\n"); 02552 return FALSE; 02553 } 02554 } else { 02555 net = hashGet(cdgNets, args[0]); 02556 } 02557 02558 if(!net) { 02559 cdgPrintf(CDG_ERROR, "ERROR: cannot find a net `%s'\n", args[0]); 02560 return FALSE; 02561 } 02562 02563 /* find best Parse */ 02564 for(l = net->parses; l != NULL; l = listNext(l)) { 02565 Parse p = listElement(l); 02566 if(!best || bCompare(p->badness, best->badness)) { 02567 best = p; 02568 } 02569 } 02570 02571 if(!best) { 02572 cdgPrintf(CDG_ERROR, "ERROR: no parse in net `%s'\n", net->id); 02573 return FALSE; 02574 } 02575 02576 ae = parse2annotation(best); 02577 writeAnnotation(ae, best->latticeId); 02578 freeAnnoEntry(ae); 02579 02580 return TRUE; 02581 } 02582 02583 /* ---------------------------------------------------------------------- 02584 Write the specified parses to XFig and LaTeX files. 02585 */ 02586 Boolean cmdWriteParses(int no, char **args) 02587 { 02588 String main_level = NULL; 02589 String graph_file = NULL; 02590 String info_file = NULL; 02591 ConstraintNet net = NULL; 02592 Level level = inputGetMainlevel(inputCurrentGrammar); 02593 02594 if (level) { 02595 main_level = level->id; 02596 } 02597 02598 if (args == NULL) { 02599 cdgPrintf(CDG_ERROR, "cmdWriteParses: ERROR: argument is NULL\n"); 02600 return FALSE; 02601 } 02602 switch (no) { 02603 case 0: 02604 case 1: 02605 cdgPrintf(CDG_ERROR, 02606 "cmdWriteParses: ERROR: writeparses [net] [main_level] Graphic-filename Info-filename\n"); 02607 cdgPrintf(CDG_ERROR, 02608 " the filenames will have appended '-i.fig' and '-i.tex',\n"); 02609 cdgPrintf(CDG_ERROR, 02610 " where i stands for the current solution number.\n"); 02611 return FALSE; 02612 case 2: 02613 graph_file = args[0]; 02614 info_file = args[1]; 02615 if (cnMostRecentlyCreatedNet != NULL) 02616 net = cnMostRecentlyCreatedNet; 02617 else { 02618 net = NULL; 02619 cdgPrintf(CDG_ERROR, 02620 "ERROR: `writeparses' needs a constraint net id or a default net\n"); 02621 return FALSE; 02622 } 02623 break; 02624 case 3: 02625 graph_file = args[1]; 02626 info_file = args[2]; 02627 net = cnFindNet(args[0]); 02628 if (!net) { 02629 cdgPrintf(CDG_ERROR, "ERROR: can't find a net `%s'\n", args[0]); 02630 return FALSE; 02631 } 02632 break; 02633 case 4: 02634 default: 02635 main_level = args[1]; 02636 graph_file = args[2]; 02637 info_file = args[3]; 02638 net = cnFindNet(args[0]); 02639 if (!net) { 02640 cdgPrintf(CDG_ERROR, "ERROR: can't find a net `%s'\n", args[0]); 02641 return FALSE; 02642 } 02643 break; 02644 } 02645 02646 if (net) { 02647 cdgCtrlCAllowed = TRUE; 02648 cdgCtrlCTrapped = FALSE; 02649 writeParses(net->parses, main_level, graph_file, info_file); 02650 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 02651 } 02652 02653 return TRUE; 02654 } 02655 02656 /* ---------------------------------------------------------------------- 02657 Print status information. 02658 */ 02659 Boolean cmdStatus(int no, char **args) 02660 { 02661 List l; 02662 Level level = inputGetMainlevel(inputCurrentGrammar); 02663 HashIterator hi; 02664 int counter = 0; 02665 02666 if (no > 0) { 02667 cdgPrintf(CDG_INFO, "INFO: `status' has no arguments\n"); 02668 } 02669 02670 cdgPrintf(CDG_DEFAULT, " constraints: %d\n", 02671 hashSize(inputCurrentGrammar->constraints)); 02672 cdgPrintf(CDG_DEFAULT, " level declarations: %d\n", 02673 listSize(inputCurrentGrammar->levels)); 02674 cdgPrintf(CDG_DEFAULT, " word forms: %d\n", 02675 hashSize(inputCurrentGrammar->lexicon)); 02676 02677 counter = 0; 02678 hi = hashIteratorNew(inputCurrentGrammar->lexicon); 02679 while ((l = hashIteratorNextValue(hi))) { 02680 counter += listSize(l); 02681 } 02682 02683 hashIteratorDelete(hi); 02684 cdgPrintf(CDG_DEFAULT, " lexical entries: %d\n", counter); 02685 cdgPrintf(CDG_DEFAULT, " wordgraphs: %d\n", 02686 listSize(inputCurrentGrammar->lattices)); 02687 cdgPrintf(CDG_DEFAULT, " annotations: %d\n", 02688 hashSize(inputCurrentGrammar->annotations)); 02689 cdgPrintf(CDG_DEFAULT, " hierarchies: %d\n", 02690 hashSize(inputCurrentGrammar->hierarchies)); 02691 cdgPrintf(CDG_DEFAULT, " parameters: %d\n", 02692 listSize(inputCurrentGrammar->parameters)); 02693 cdgPrintf(CDG_DEFAULT, "\n"); 02694 02695 cdgPrintf(CDG_DEFAULT, " parses: %d\n", 02696 hashSize(cdgParses)); 02697 cdgPrintf(CDG_DEFAULT, "\n"); 02698 02699 cdgPrintf(CDG_DEFAULT, " constraint nets: %d\n", 02700 hashSize(cdgNets)); 02701 cdgPrintf(CDG_DEFAULT, "\n"); 02702 cdgPrintf(CDG_DEFAULT, " verbosity: %ld\n", hkVerbosity); 02703 cdgPrintf(CDG_DEFAULT, " show deleted values: %s\n", 02704 cnShowDeletedFlag ? "yes" : "no"); 02705 cdgPrintf(CDG_DEFAULT, " use statistics: %s\n", 02706 statUseStatisticsFlag ? "yes" : "no"); 02707 cdgPrintf(CDG_DEFAULT, " search modifies net: %s\n", 02708 nsSearchModifiesNetFlag ? "yes" : "no"); 02709 cdgPrintf(CDG_DEFAULT, "automatic comparison: %s\n", 02710 nsAutoCompare ? "yes" : "no"); 02711 cdgPrintf(CDG_DEFAULT, " normalization: %s\n", 02712 nsNormalization == NSNOff ? "off" : nsNormalization == 02713 NSNLinear ? "linear" : nsNormalization == 02714 NSNSquare ? "square" : nsNormalization == 02715 NSNDepth ? "depth" : nsNormalization == 02716 NSNBreadth ? "breadth" : "unknown"); 02717 cdgPrintf(CDG_DEFAULT, " subsumes warnings: %s\n", 02718 evalSloppySubsumesWarnings ? "sloppy" : "full"); 02719 cdgPrintf(CDG_DEFAULT, " build edges: %s\n", 02720 cnEdgesFlag == cnEdgesOff ? "no" : "yes"); 02721 cdgPrintf(CDG_DEFAULT, "unary pruning factor: %f\n", cnUnaryPruningFraction); 02722 cdgPrintf(CDG_DEFAULT, " caching: %s\n", 02723 scUseCache ? "yes" : "no"); 02724 02725 cdgPrintf(CDG_DEFAULT, "compact level values: %s\n", 02726 lgCompactLVs ? "yes" : "no"); 02727 cdgPrintf(CDG_DEFAULT, " evaluation method: %s\n", 02728 evalEvaluationMethod == 02729 EMTCompiled ? "compiled" : evalEvaluationMethod == 02730 EMTInterpreted ? "interpreted" : "invalid"); 02731 cdgPrintf(CDG_DEFAULT, " peek value method: %s\n", 02732 evalPeekValueMethod == 02733 EMTCompiled ? "compiled" : evalPeekValueMethod == 02734 EMTInterpreted ? "interpreted" : "invalid"); 02735 cdgPrintf(CDG_DEFAULT, " acoustics method: %s\n", 02736 vmAcoustics == vmAcOff ? "off" : vmAcoustics == 02737 vmAcLinear ? "linear" : vmAcoustics == 02738 vmAcScaled ? "scaled" : "invalid"); 02739 02740 cdgPrintf(CDG_DEFAULT, " sort nodes: %s\n", 02741 cnSortNodesMethod == 0 ? "no" : 02742 cnSortNodesMethod == 1 ? "By level priority" : 02743 cnSortNodesMethod == 2 ? "By increasing domain size" : "unknown"); 02744 02745 cdgPrintf(CDG_DEFAULT, " main level: %s\n", 02746 level ? level->id : "<undefined>"); 02747 02748 cdgPrintf(CDG_DEFAULT, " #shared strings: %d\n", strStoreSize()); 02749 02750 #if 0 02751 #ifndef __CYGWIN__ 02752 { 02753 struct rlimit cpu; 02754 struct rlimit mem; 02755 struct rusage ru; 02756 02757 if (getrusage(RUSAGE_SELF, &ru) || 02758 getrlimit(RLIMIT_CPU, &cpu) || getrlimit(RLIMIT_AS, &mem)) { 02759 cdgPrintf(CDG_DEFAULT, 02760 "WARNING: can't get rlimit or rusage: %s\n", strerror(errno)); 02761 } else { 02762 /* 02763 * I'm not sure how to compute current memory usage. ru.ru_maxrss gives the ``maximum 02764 * resident set size'' in pages. Currently it doesn't work. */ 02765 cdgPrintf(CDG_DEFAULT, 02766 " cpu usage: %d.%06d sec ", 02767 ru.ru_utime.tv_sec + ru.ru_stime.tv_sec, 02768 ru.ru_utime.tv_usec + ru.ru_stime.tv_usec); 02769 if (cpu.rlim_cur == RLIM_INFINITY) { 02770 cdgPrintf(CDG_DEFAULT, "(unlimited)\n"); 02771 } else { 02772 cdgPrintf(CDG_DEFAULT, "of %d sec\n", cpu.rlim_cur); 02773 } 02774 cdgPrintf(CDG_DEFAULT, 02775 " memory usage: %d bytes ", 02776 ru.ru_maxrss * getpagesize()); 02777 if (mem.rlim_cur == RLIM_INFINITY) { 02778 cdgPrintf(CDG_DEFAULT, "(unlimited)\n"); 02779 } else { 02780 cdgPrintf(CDG_DEFAULT, "of %d bytes\n", mem.rlim_cur); 02781 } 02782 cdgPrintf(CDG_DEFAULT, "\n"); 02783 } 02784 } 02785 #endif 02786 #endif 02787 02788 cdgPrintf(CDG_DEFAULT, " %2d loaded file(s):\n", 02789 listSize(inputCurrentGrammar->files)); 02790 for (l = inputCurrentGrammar->files; l != NULL; l = listNext(l)) { 02791 cdgPrintf(CDG_DEFAULT, " %s\n", (String) listElement(l)); 02792 } 02793 02794 cdgPrintf(CDG_DEFAULT, "\n"); 02795 02796 #if 0 02797 cdgPrintf(CDG_DEFAULT, "CDG_HINT %s\n", 02798 hkVerbosity & CDG_HINT ? "on" : "off"); 02799 cdgPrintf(CDG_DEFAULT, "CDG_INFO %s\n", 02800 hkVerbosity & CDG_INFO ? "on" : "off"); 02801 cdgPrintf(CDG_DEFAULT, "CDG_WARNING %s\n", 02802 hkVerbosity & CDG_WARNING ? "on" : "off"); 02803 cdgPrintf(CDG_DEFAULT, "CDG_PROLOG %s\n", 02804 hkVerbosity & CDG_PROLOG ? "on" : "off"); 02805 cdgPrintf(CDG_DEFAULT, "CDG_EVAL %s\n", 02806 hkVerbosity & CDG_EVAL ? "on" : "off"); 02807 cdgPrintf(CDG_DEFAULT, "CDG_SEARCHRESULT %s\n", 02808 hkVerbosity & CDG_SEARCHRESULT ? "on" : "off"); 02809 cdgPrintf(CDG_DEFAULT, "CDG_PROFILE %s\n", 02810 hkVerbosity & CDG_PROFILE ? "on" : "off"); 02811 cdgPrintf(CDG_DEFAULT, "CDG_HOOK %s\n", 02812 hkVerbosity & CDG_HOOK ? "on" : "off"); 02813 cdgPrintf(CDG_DEFAULT, "CDG_ERROR %s\n", 02814 hkVerbosity & CDG_ERROR ? "on" : "off"); 02815 cdgPrintf(CDG_DEFAULT, "CDG_DEBUG %s\n", 02816 hkVerbosity & CDG_DEBUG ? "on" : "off"); 02817 cdgPrintf(CDG_DEFAULT, "CDG_DEFAULT %s\n", 02818 hkVerbosity & CDG_DEFAULT ? "on" : "off"); 02819 cdgPrintf(CDG_DEFAULT, "CDG_PROGRESS %s\n", 02820 hkVerbosity & CDG_PROGRESS ? "on" : "off"); 02821 cdgPrintf(CDG_DEFAULT, "CDG_XML %s\n", 02822 hkVerbosity & CDG_XML ? "on" : "off"); 02823 #endif 02824 02825 /* print out the symbol table */ 02826 { 02827 String name; 02828 List names = setReturnListOfNames(); 02829 List l; 02830 02831 cdgPrintf(CDG_DEFAULT, "\nsymbol table:\n"); 02832 02833 for (l = names; l; l = listNext(l)) { 02834 name = listElement(l); 02835 cdgPrintf(CDG_DEFAULT, " "); 02836 setPrint(CDG_DEFAULT, name); 02837 } 02838 listDelete(names); 02839 } 02840 02841 return TRUE; 02842 } 02843 02844 /* ---------------------------------------------------------------------- 02845 Discard all loaded and computed information. 02846 */ 02847 Boolean cmdReset(int no, char **args) 02848 { 02849 02850 /* just to be sure */ 02851 if (no > 0) { 02852 cdgPrintf(CDG_ERROR, "ERROR: `reset' takes no arguments.\n"); 02853 return FALSE; 02854 } 02855 02856 cdgDeleteComputed(); 02857 02858 /* free loaded items */ 02859 inputFreeInput(inputCurrentGrammar); 02860 inputCurrentGrammar = inputNewInput(); 02861 02862 /* A lot changed since we were last in London... */ 02863 inputCacheInput(inputCurrentGrammar); 02864 02865 return TRUE; 02866 } 02867 02868 /* ---------------------------------------------------------------------- 02869 Load one or more files. 02870 */ 02871 Boolean cmdLoad(int no, char **args) 02872 { 02873 int i; 02874 Boolean success = FALSE; 02875 Boolean result = TRUE; 02876 Input meanResult = inputNewInput(); 02877 02878 if (args == NULL) { 02879 cdgPrintf(CDG_ERROR, "cmdLoad: ERROR: argument is NULL\n"); 02880 return FALSE; 02881 } 02882 02883 /* load all files */ 02884 for (i = 0; i < no && args[i] != NULL; i++) { 02885 02886 result = inputLoad(args[i]); 02887 if (!result) 02888 break; 02889 02890 if (parseNoOfErrors == 0) { 02891 if (strlen(parseCurrentFile) >= 3 && 02892 strcmp(&(parseCurrentFile[strlen(parseCurrentFile) - 3]), 02893 ".so") == 0) { 02894 cdgPrintf(CDG_INFO, "INFO: hooking compiled constraints\n"); 02895 evalEvaluationMethod = EMTCompiled; 02896 } else { 02897 cdgPrintf(CDG_INFO, "INFO: file `%s' loaded: ", parseCurrentFile); 02898 cdgPrintf(CDG_INFO, "%d/%d/%d/%d/%d/%d/%d/%d\n", 02899 hashSize(parseResult->constraints), 02900 listSize(parseResult->levels), 02901 hashSize(parseResult->lexicon), 02902 listSize(parseResult->lattices), 02903 hashSize(parseResult->annotations), 02904 hashSize(parseResult->hierarchies), 02905 listSize(parseResult->parameters), 02906 hashSize(parseResult->maps)); 02907 } 02908 if (parseNoOfWarnings != 0) { 02909 cdgPrintf(CDG_INFO, "INFO: %d warning(s)\n", parseNoOfWarnings); 02910 } 02911 02912 /* combine already loaded items and just loaded items */ 02913 mergeInput(meanResult, parseResult); 02914 02915 /* All the stuff except parseResult is free'd in mergeInput. */ 02916 memFree(parseResult); 02917 success = TRUE; 02918 } else { 02919 /* There were errors. Free and ignore the new items. */ 02920 cdgPrintf(CDG_INFO, "ERROR: %d error(s), input ignored\n", 02921 parseNoOfErrors); 02922 inputFreeInput(parseResult); 02923 parseResult = NULL; 02924 result = FALSE; 02925 break; 02926 } 02927 parseResult = NULL; 02928 } 02929 02930 /* we loaded at least one file */ 02931 if (success) { 02932 02933 cdgDeleteComputed(); 02934 02935 /* promote new data to current data */ 02936 mergeInput(inputCurrentGrammar, meanResult); 02937 cdgExecPragmas(meanResult->pragmas); 02938 inputCacheInput(inputCurrentGrammar); 02939 memFree(meanResult); 02940 } 02941 02942 return result; 02943 } 02944 02945 /* ---------------------------------------------------------------------- 02946 Print the General Public License. 02947 */ 02948 Boolean cmdLicense(int no, char **args) 02949 { 02950 cdgPrintf(CDG_DEFAULT, 02951 "\n GNU GENERAL PUBLIC LICENSE\n" 02952 " Version 2, June 1991\n" 02953 "\n" 02954 " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n" 02955 " 675 Mass Ave, Cambridge, MA 02139, USA\n" 02956 " Everyone is permitted to copy and distribute verbatim copies\n" 02957 " of this license document, but changing it is not allowed.\n" 02958 "\n" 02959 " Preamble\n" 02960 "\n" 02961 " The licenses for most software are designed to take away your\n" 02962 "freedom to share and change it. By contrast, the GNU General Public\n" 02963 "License is intended to guarantee your freedom to share and change free\n" 02964 "software--to make sure the software is free for all its users. This\n" 02965 "General Public License applies to most of the Free Software\n" 02966 "Foundation's software and to any other program whose authors commit to\n" 02967 "using it. (Some other Free Software Foundation software is covered by\n" 02968 "the GNU Library General Public License instead.) You can apply it to\n" 02969 "your programs, too.\n" 02970 "\n" 02971 " When we speak of free software, we are referring to freedom, not\n" 02972 "price. Our General Public Licenses are designed to make sure that you\n" 02973 "have the freedom to distribute copies of free software (and charge for\n" 02974 "this service if you wish), that you receive source code or can get it\n" 02975 "if you want it, that you can change the software or use pieces of it\n" 02976 "in new free programs; and that you know you can do these things.\n" 02977 "\n" 02978 " To protect your rights, we need to make restrictions that forbid\n" 02979 "anyone to deny you these rights or to ask you to surrender the rights.\n" 02980 "These restrictions translate to certain responsibilities for you if you\n" 02981 "distribute copies of the software, or if you modify it.\n" 02982 "\n" 02983 " For example, if you distribute copies of such a program, whether\n" 02984 "gratis or for a fee, you must give the recipients all the rights that\n" 02985 "you have. You must make sure that they, too, receive or can get the\n" 02986 "source code. And you must show them these terms so they know their\n" 02987 "rights.\n" 02988 "\n" 02989 " We protect your rights with two steps: (1) copyright the software, and\n" 02990 "(2) offer you this license which gives you legal permission to copy,\n" 02991 "distribute and/or modify the software.\n" 02992 "\n" 02993 " Also, for each author's protection and ours, we want to make certain\n" 02994 "that everyone understands that there is no warranty for this free\n" 02995 "software. If the software is modified by someone else and passed on, we\n" 02996 "want its recipients to know that what they have is not the original, so\n" 02997 "that any problems introduced by others will not reflect on the original\n" 02998 "authors' reputations.\n" 02999 "\n" 03000 " Finally, any free program is threatened constantly by software\n" 03001 "patents. We wish to avoid the danger that redistributors of a free\n" 03002 "program will individually obtain patent licenses, in effect making the\n" 03003 "program proprietary. To prevent this, we have made it clear that any\n" 03004 "patent must be licensed for everyone's free use or not licensed at all.\n" 03005 "\n" 03006 " The precise terms and conditions for copying, distribution and\n" 03007 "modification follow.\n" 03008 "\n" 03009 " GNU GENERAL PUBLIC LICENSE\n" 03010 " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" 03011 "\n" 03012 " 0. This License applies to any program or other work which contains\n" 03013 "a notice placed by the copyright holder saying it may be distributed\n" 03014 "under the terms of this General Public License. The \"Program\", below,\n" 03015 "refers to any such program or work, and a \"work based on the Program\"\n" 03016 "means either the Program or any derivative work under copyright law:\n" 03017 "that is to say, a work containing the Program or a portion of it,\n" 03018 "either verbatim or with modifications and/or translated into another\n" 03019 "language. (Hereinafter, translation is included without limitation in\n" 03020 "the term \"modification\".) Each licensee is addressed as \"you\".\n" 03021 "\n" 03022 "Activities other than copying, distribution and modification are not\n" 03023 "covered by this License; they are outside its scope. The act of\n" 03024 "running the Program is not restricted, and the output from the Program\n" 03025 "is covered only if its contents constitute a work based on the\n" 03026 "Program (independent of having been made by running the Program).\n" 03027 "Whether that is true depends on what the Program does.\n" 03028 "\n" 03029 " 1. You may copy and distribute verbatim copies of the Program's\n" 03030 "source code as you receive it, in any medium, provided that you\n" 03031 "conspicuously and appropriately publish on each copy an appropriate\n" 03032 "copyright notice and disclaimer of warranty; keep intact all the\n" 03033 "notices that refer to this License and to the absence of any warranty;\n" 03034 "and give any other recipients of the Program a copy of this License\n" 03035 "along with the Program.\n" 03036 "\n" 03037 "You may charge a fee for the physical act of transferring a copy, and\n" 03038 "you may at your option offer warranty protection in exchange for a fee.\n" 03039 "\n" 03040 " 2. You may modify your copy or copies of the Program or any portion\n" 03041 "of it, thus forming a work based on the Program, and copy and\n" 03042 "distribute such modifications or work under the terms of Section 1\n" 03043 "above, provided that you also meet all of these conditions:\n" 03044 "\n" 03045 " a) You must cause the modified files to carry prominent notices\n" 03046 " stating that you changed the files and the date of any change.\n" 03047 "\n" 03048 " b) You must cause any work that you distribute or publish, that in\n" 03049 " whole or in part contains or is derived from the Program or any\n" 03050 " part thereof, to be licensed as a whole at no charge to all third\n" 03051 " parties under the terms of this License.\n" 03052 "\n" 03053 " c) If the modified program normally reads commands interactively\n" 03054 " when run, you must cause it, when started running for such\n" 03055 " interactive use in the most ordinary way, to print or display an\n" 03056 " announcement including an appropriate copyright notice and a\n" 03057 " notice that there is no warranty (or else, saying that you provide\n" 03058 " a warranty) and that users may redistribute the program under\n" 03059 " these conditions, and telling the user how to view a copy of this\n" 03060 " License. (Exception: if the Program itself is interactive but\n" 03061 " does not normally print such an announcement, your work based on\n" 03062 " the Program is not required to print an announcement.)\n" 03063 "\n" 03064 "These requirements apply to the modified work as a whole. If\n" 03065 "identifiable sections of that work are not derived from the Program,\n" 03066 "and can be reasonably considered independent and separate works in\n" 03067 "themselves, then this License, and its terms, do not apply to those\n" 03068 "sections when you distribute them as separate works. But when you\n" 03069 "distribute the same sections as part of a whole which is a work based\n" 03070 "on the Program, the distribution of the whole must be on the terms of\n" 03071 "this License, whose permissions for other licensees extend to the\n" 03072 "entire whole, and thus to each and every part regardless of who wrote it.\n" 03073 "\n" 03074 "Thus, it is not the intent of this section to claim rights or contest\n" 03075 "your rights to work written entirely by you; rather, the intent is to\n" 03076 "exercise the right to control the distribution of derivative or\n" 03077 "collective works based on the Program.\n" 03078 "\n" 03079 "In addition, mere aggregation of another work not based on the Program\n" 03080 "with the Program (or with a work based on the Program) on a volume of\n" 03081 "a storage or distribution medium does not bring the other work under\n" 03082 "the scope of this License.\n" 03083 "\n" 03084 " 3. You may copy and distribute the Program (or a work based on it,\n" 03085 "under Section 2) in object code or executable form under the terms of\n" 03086 "Sections 1 and 2 above provided that you also do one of the following:\n" 03087 "\n" 03088 " a) Accompany it with the complete corresponding machine-readable\n" 03089 " source code, which must be distributed under the terms of Sections\n" 03090 " 1 and 2 above on a medium customarily used for software interchange; or,\n" 03091 "\n" 03092 " b) Accompany it with a written offer, valid for at least three\n" 03093 " years, to give any third party, for a charge no more than your\n" 03094 " cost of physically performing source distribution, a complete\n" 03095 " machine-readable copy of the corresponding source code, to be\n" 03096 " distributed under the terms of Sections 1 and 2 above on a medium\n" 03097 " customarily used for software interchange; or,\n" 03098 "\n" 03099 " c) Accompany it with the information you received as to the offer\n" 03100 " to distribute corresponding source code. (This alternative is\n" 03101 " allowed only for noncommercial distribution and only if you\n" 03102 " received the program in object code or executable form with such\n" 03103 " an offer, in accord with Subsection b above.)\n" 03104 "\n" 03105 "The source code for a work means the preferred form of the work for\n" 03106 "making modifications to it. For an executable work, complete source\n" 03107 "code means all the source code for all modules it contains, plus any\n" 03108 "associated interface definition files, plus the scripts used to\n" 03109 "control compilation and installation of the executable. However, as a\n" 03110 "special exception, the source code distributed need not include\n" 03111 "anything that is normally distributed (in either source or binary\n" 03112 "form) with the major components (compiler, kernel, and so on) of the\n" 03113 "operating system on which the executable runs, unless that component\n" 03114 "itself accompanies the executable.\n" 03115 "\n" 03116 "If distribution of executable or object code is made by offering\n" 03117 "access to copy from a designated place, then offering equivalent\n" 03118 "access to copy the source code from the same place counts as\n" 03119 "distribution of the source code, even though third parties are not\n" 03120 "compelled to copy the source along with the object code.\n" 03121 "\n" 03122 "4. You may not copy, modify, sublicense, or distribute the Program\n" 03123 "except as expressly provided under this License. Any attempt\n" 03124 "otherwise to copy, modify, sublicense or distribute the Program is\n" 03125 "void, and will automatically terminate your rights under this License.\n" 03126 "However, parties who have received copies, or rights, from you under\n" 03127 "this License will not have their licenses terminated so long as such\n" 03128 "parties remain in full compliance.\n" 03129 "\n" 03130 " 5. You are not required to accept this License, since you have not\n" 03131 "signed it. However, nothing else grants you permission to modify or\n" 03132 "distribute the Program or its derivative works. These actions are\n" 03133 "prohibited by law if you do not accept this License. Therefore, by\n" 03134 "modifying or distributing the Program (or any work based on the\n" 03135 "Program), you indicate your acceptance of this License to do so, and\n" 03136 "all its terms and conditions for copying, distributing or modifying\n" 03137 "the Program or works based on it.\n" 03138 "\n" 03139 " 6. Each time you redistribute the Program (or any work based on the\n" 03140 "Program), the recipient automatically receives a license from the\n" 03141 "original licensor to copy, distribute or modify the Program subject to\n" 03142 "these terms and conditions. You may not impose any further\n" 03143 "restrictions on the recipients' exercise of the rights granted herein.\n" 03144 "You are not responsible for enforcing compliance by third parties to\n" 03145 "this License.\n" 03146 "\n" 03147 " 7. If, as a consequence of a court judgment or allegation of patent\n" 03148 "infringement or for any other reason (not limited to patent issues),\n" 03149 "conditions are imposed on you (whether by court order, agreement or\n" 03150 "otherwise) that contradict the conditions of this License, they do not\n" 03151 "excuse you from the conditions of this License. If you cannot\n" 03152 "distribute so as to satisfy simultaneously your obligations under this\n" 03153 "License and any other pertinent obligations, then as a consequence you\n" 03154 "may not distribute the Program at all. For example, if a patent\n" 03155 "license would not permit royalty-free redistribution of the Program by\n" 03156 "all those who receive copies directly or indirectly through you, then\n" 03157 "the only way you could satisfy both it and this License would be to\n" 03158 "refrain entirely from distribution of the Program.\n" 03159 "\n" 03160 "If any portion of this section is held invalid or unenforceable under\n" 03161 "any particular circumstance, the balance of the section is intended to\n" 03162 "apply and the section as a whole is intended to apply in other\n" 03163 "circumstances.\n" 03164 "\n" 03165 "It is not the purpose of this section to induce you to infringe any\n" 03166 "patents or other property right claims or to contest validity of any\n" 03167 "such claims; this section has the sole purpose of protecting the\n" 03168 "integrity of the free software distribution system, which is\n" 03169 "implemented by public license practices. Many people have made\n" 03170 "generous contributions to the wide range of software distributed\n" 03171 "through that system in reliance on consistent application of that\n" 03172 "system; it is up to the author/donor to decide if he or she is willing\n" 03173 "to distribute software through any other system and a licensee cannot\n" 03174 "impose that choice.\n" 03175 "\n" 03176 "This section is intended to make thoroughly clear what is believed to\n" 03177 "be a consequence of the rest of this License.\n" 03178 "\n" 03179 " 8. If the distribution and/or use of the Program is restricted in\n" 03180 "certain countries either by patents or by copyrighted interfaces, the\n" 03181 "original copyright holder who places the Program under this License\n" 03182 "may add an explicit geographical distribution limitation excluding\n" 03183 "those countries, so that distribution is permitted only in or among\n" 03184 "countries not thus excluded. In such case, this License incorporates\n" 03185 "the limitation as if written in the body of this License.\n" 03186 "\n" 03187 " 9. The Free Software Foundation may publish revised and/or new versions\n" 03188 "of the General Public License from time to time. Such new versions will\n" 03189 "be similar in spirit to the present version, but may differ in detail to\n" 03190 "address new problems or concerns.\n" 03191 "\n" 03192 "Each version is given a distinguishing version number. If the Program\n" 03193 "specifies a version number of this License which applies to it and \"any\n" 03194 "later version\", you have the option of following the terms and conditions\n" 03195 "either of that version or of any later version published by the Free\n" 03196 "Software Foundation. If the Program does not specify a version number of\n" 03197 "this License, you may choose any version ever published by the Free Software\n" 03198 "Foundation.\n" 03199 "\n" 03200 " 10. If you wish to incorporate parts of the Program into other free\n" 03201 "programs whose distribution conditions are different, write to the author\n" 03202 "to ask for permission. For software which is copyrighted by the Free\n" 03203 "Software Foundation, write to the Free Software Foundation; we sometimes\n" 03204 "make exceptions for this. Our decision will be guided by the two goals\n" 03205 "of preserving the free status of all derivatives of our free software and\n" 03206 "of promoting the sharing and reuse of software generally.\n" 03207 "\n" 03208 " NO WARRANTY\n" 03209 "\n" 03210 " 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" 03211 "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" 03212 "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" 03213 "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" 03214 "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" 03215 "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" 03216 "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" 03217 "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" 03218 "REPAIR OR CORRECTION.\n" 03219 "\n" 03220 " 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" 03221 "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" 03222 "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" 03223 "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" 03224 "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" 03225 "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" 03226 "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" 03227 "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" 03228 "POSSIBILITY OF SUCH DAMAGES.\n" 03229 "\n" " END OF TERMS AND CONDITIONS\n" "\n"); 03230 return TRUE; 03231 } 03232 03233 /* ---------------------------------------------------------------------- 03234 Print the CDG version. 03235 */ 03236 Boolean cmdVersion(int no, char **args) 03237 { 03238 cdgPrintf(CDG_DEFAULT, STARTUPMSG); 03239 03240 return TRUE; 03241 } 03242 03243 /* ---------------------------------------------------------------------- 03244 Build a new constraint net. 03245 */ 03246 Boolean cmdNewnet(int no, char **args) 03247 { 03248 ConstraintNet net; 03249 String id; 03250 Lattice lat; 03251 Timer profileTime; 03252 Boolean result = TRUE; 03253 unsigned long duration; 03254 Boolean buildLVs = TRUE; 03255 03256 if (args == NULL) { 03257 cdgPrintf(CDG_ERROR, "cmdNewnet: ERROR: argument is NULL\n"); 03258 return FALSE; 03259 } 03260 if (no < 1 || (id = args[0]) == NULL) { 03261 if (inputMostRecentlyCreatedLattice == NULL) { 03262 cdgPrintf(CDG_ERROR, 03263 "ERROR: `newnet' needs a word graph id or a default word graph.\n"); 03264 return FALSE; 03265 } 03266 cdgPrintf(CDG_INFO, 03267 "INFO: using most recently created word graph `%s'\n", 03268 inputMostRecentlyCreatedLattice->id); 03269 lat = inputMostRecentlyCreatedLattice; 03270 } else { 03271 03272 if (!(lat = findLattice(id))) { 03273 cdgPrintf(CDG_ERROR, "ERROR: `newnet': wordgraph `%s' unknown\n", id); 03274 return FALSE; 03275 } 03276 } 03277 03278 cdgCtrlCAllowed = TRUE; 03279 cdgCtrlCTrapped = FALSE; 03280 03281 profileTime = timerNew(); 03282 net = cnBuild(lat, buildLVs); 03283 duration = timerElapsed(profileTime); 03284 timerFree(profileTime); 03285 03286 if (net == NULL) { 03287 if (!cdgCtrlCTrapped) { 03288 cdgPrintf(CDG_WARNING, "ERROR: invalid net\n"); 03289 } 03290 result = FALSE; 03291 } else { 03292 cdgPrintf(CDG_PROFILE, "PROFILE: newnet took %lums\n", duration); 03293 hashSet(cdgNets, net->id, net); 03294 cnPrintInfo(net); 03295 writeXmlNetInfo(net); 03296 } 03297 03298 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 03299 03300 return result; 03301 } 03302 03303 /* ---------------------------------------------------------------------- 03304 Restore the specified net to original state. 03305 */ 03306 Boolean cmdRenewnet(int no, char **args) 03307 { 03308 ConstraintNet net; 03309 int i; 03310 03311 if (args == NULL) { 03312 cdgPrintf(CDG_ERROR, "cmdRenewNet: ERROR: argument is NULL\n"); 03313 return FALSE; 03314 } 03315 03316 /* get net */ 03317 net = NULL; 03318 if (no > 0) { 03319 for (i = 0; i < no && args[i] != NULL; i++) { 03320 net = cnFindNet(args[i]); 03321 if (!net) { 03322 cdgPrintf(CDG_INFO, "INFO: can't find a net `%s'\n", args[i]); 03323 return FALSE; 03324 } 03325 } 03326 } else { 03327 net = cnMostRecentlyCreatedNet; 03328 } 03329 03330 if (!net) { 03331 cdgPrintf(CDG_ERROR, 03332 "ERROR: `renewnet' needs a constraint net id or a default net\n"); 03333 return FALSE; 03334 } else { 03335 cnRenew(net); 03336 cnPrintInfo(net); 03337 writeXmlNetInfo(net); 03338 } 03339 03340 return TRUE; 03341 } 03342 03343 /* ---------------------------------------------------------------------- 03344 Build a new wordgraph. 03345 */ 03346 Boolean cmdInputwordgraph(int no, char **args) 03347 { 03348 Lattice lat; 03349 Arc arc; 03350 String id; 03351 int i; 03352 static int counter = 0; 03353 03354 if (args == NULL) { 03355 cdgPrintf(CDG_ERROR, "cmdInputwordgraph: ERROR: argument is NULL\n"); 03356 return FALSE; 03357 } 03358 03359 if (no < 1 || (id = args[0]) == NULL) { 03360 cdgPrintf(CDG_ERROR, 03361 "`inputwordgraph' needs at least one word as an argument.\n"); 03362 return FALSE; 03363 } 03364 03365 lat = (Lattice) memMalloc(sizeof (LatticeStruct)); 03366 /* There is no guarantee that no longer ids are needed but ... */ 03367 lat->id = strPrintf("wordgraph%d", counter++); 03368 lat->filename = strRegister("*USER*"); 03369 lat->lineNo = 0; 03370 03371 lat->arcs = NULL; 03372 for (i = 0; i < no && args[i] != NULL; i++) { 03373 arc = newArc(i, i + 1, i, 03374 strRegister(args[i]), 0.0, NULL, 0, 0); 03375 03376 lat->arcs = listAppendElement(lat->arcs, arc); 03377 } 03378 inputScanLattice(lat); 03379 03380 inputCurrentGrammar->lattices = 03381 listAppendElement(inputCurrentGrammar->lattices, lat); 03382 cdgPrintf(CDG_INFO, "INFO: wordgraph id: %s, #arcs: %d\n", lat->id, i); 03383 inputMostRecentlyCreatedLattice = lat; 03384 inputCurrentGrammar->xcdgwordgraphsToDate = FALSE; 03385 03386 return TRUE; 03387 } 03388 03389 /* ---------------------------------------------------------------------- 03390 Print the distance matrix of the specified net. 03391 */ 03392 Boolean cmdDistance(int no, char **args) 03393 { 03394 LexemGraph lg; 03395 LexemNode a, b; 03396 ConstraintNet net; 03397 int i, j, k; 03398 03399 if (args == NULL) { 03400 cdgPrintf(CDG_ERROR, "cmdDistance: ERROR: argument is NULL\n"); 03401 return FALSE; 03402 } 03403 03404 if (no < 1 || args[0] == NULL) { 03405 cdgPrintf(CDG_ERROR, "ERROR: `distance' needs a constraint net id\n"); 03406 return FALSE; 03407 } 03408 03409 net = cnFindNet(args[0]); 03410 if (!net) { 03411 cdgPrintf(CDG_ERROR, 03412 "ERROR: `distance': constraint net `%s' unknown\n", args[0]); 03413 return FALSE; 03414 } 03415 03416 lg = net->lexemgraph; 03417 03418 cdgPrintf(CDG_DEFAULT, " "); 03419 for (i = 0; i < vectorSize(lg->graphemnodes); i++) { 03420 a = (LexemNode) 03421 listElement(((GraphemNode) vectorElement(lg->graphemnodes, i))->lexemes); 03422 cdgPrintf(CDG_DEFAULT, "%6.6s ", a->lexem->word); 03423 } 03424 cdgPrintf(CDG_DEFAULT, "\n\n"); 03425 03426 for (i = 0; i < vectorSize(lg->graphemnodes); i++) { 03427 a = (LexemNode) 03428 listElement(((GraphemNode) vectorElement(lg->graphemnodes, i))->lexemes); 03429 cdgPrintf(CDG_DEFAULT, "%6.6s ", a->lexem->word); 03430 for (j = 0; j < vectorSize(lg->graphemnodes); j++) { 03431 b = (LexemNode) 03432 listElement(((GraphemNode) vectorElement(lg->graphemnodes, j))->lexemes); 03433 k = lgDistanceOfNodes(lg, a, b); 03434 if (k == 0) 03435 cdgPrintf(CDG_DEFAULT, " "); 03436 else 03437 cdgPrintf(CDG_DEFAULT, "%+4.4d ", k); 03438 } 03439 cdgPrintf(CDG_DEFAULT, "\n"); 03440 } 03441 03442 return TRUE; 03443 } 03444 03445 /* ---------------------------------------------------------------------- 03446 Report whether the specified constraints are suitable 03447 for processing underspecified subordinations. 03448 */ 03449 Boolean cmdNonSpecCompatible(int no, char **args) 03450 { 03451 List constraints, l; 03452 Constraint c, foundConstraint; 03453 char usage[] = "usage: nonspeccompatible [constraint]\n"; 03454 03455 if (args == NULL) { 03456 cdgPrintf(CDG_ERROR, "ERROR: argument is NULL\n"); 03457 return FALSE; 03458 } 03459 03460 if (no > 1) { 03461 cdgPrintf(CDG_ERROR, "ERROR: wrong no of parameters\n" " %s", usage); 03462 return FALSE; 03463 } 03464 03465 constraints = incGetNonSpecIncompatibles(); 03466 03467 if (no == 0) { 03468 if (listSize(constraints) == 0) { 03469 cdgPrintf(CDG_DEFAULT, "all %d constraints are compatible.\n", 03470 hashSize(inputCurrentGrammar->constraints)); 03471 } else { 03472 for (l = constraints; l; l = listNext(l)) { 03473 c = listElement(l); 03474 cdgPrintf(CDG_DEFAULT, "%s:%d: error in %s\n", 03475 c->filename, c->lineNo, c->id); 03476 } 03477 cdgPrintf(CDG_INFO, "INFO: %d incompatible constraints out of %d:\n", 03478 listSize(constraints), 03479 hashSize(inputCurrentGrammar->constraints)); 03480 } 03481 } else { 03482 /* find constraint */ 03483 foundConstraint = hashGet(inputCurrentGrammar->constraints, args[0]); 03484 if (!foundConstraint) { 03485 cdgPrintf(CDG_ERROR, "ERROR: unknown constraint `%s'\n", args[0]); 03486 return FALSE; 03487 } else { 03488 cdgPrintf(CDG_DEFAULT, "INFO: constraint `%s' is %s.\n", 03489 args[0], 03490 (listIndex(constraints, foundConstraint)) ? "incompatible" : 03491 "ok"); 03492 } 03493 } 03494 03495 return TRUE; 03496 } 03497 03498 /* ---------------------------------------------------------------------- 03499 Parsing problems are created incrementally over prefixes 03500 of the word graph and solved individually, with the solution of one 03501 problem guiding the search in the next one. 03502 */ 03503 Boolean cmdIncrementalCompletion(int no, char **args) 03504 { 03505 String id; 03506 Lattice lat = NULL; 03507 Timer profileTime; 03508 CnEdgesType oldcnEdgesFlag; 03509 Boolean oldscUseCache; 03510 Boolean oldnsSearchModifiesNetFlag; 03511 Boolean result; 03512 03513 /* interactive method is called with `interactive' as wordgraph */ 03514 if (no == 0) { 03515 cdgPrintf(CDG_ERROR, "ERROR: incrementalcompletion word_graph\n"); 03516 cdgPrintf(CDG_ERROR, 03517 " use interactive as word_graph to run the interactive method\n"); 03518 return FALSE; 03519 } 03520 03521 id = args[0]; 03522 no--; 03523 args = &args[1]; 03524 if (strcmp(id, "interactive") == 0) { 03525 lat = NULL; 03526 cdgPrintf(CDG_INFO, "INFO: Running in interactive mode\n"); 03527 } else { 03528 if (!(lat = findLattice(id))) { 03529 cdgPrintf(CDG_ERROR, 03530 "ERROR: `incrementalcompletion': wordgraph `%s' unknown\n", id); 03531 return FALSE; 03532 } 03533 } 03534 03535 cdgCtrlCAllowed = TRUE; 03536 cdgCtrlCTrapped = FALSE; 03537 oldcnEdgesFlag = cnEdgesFlag; 03538 cnEdgesFlag = cnEdgesOff; 03539 oldscUseCache = scUseCache; 03540 scUseCache = FALSE; 03541 oldnsSearchModifiesNetFlag = nsSearchModifiesNetFlag; 03542 nsSearchModifiesNetFlag = FALSE; 03543 profileTime = timerNew(); 03544 result = (icIncrementalCompletion(lat, icParams, no, args) >= 0); 03545 cnEdgesFlag = oldcnEdgesFlag; 03546 scUseCache = oldscUseCache; 03547 nsSearchModifiesNetFlag = oldnsSearchModifiesNetFlag; 03548 03549 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 03550 03551 cdgPrintf(CDG_PROFILE, 03552 "PROFILE: incrementalcompletion took %lums\n", 03553 timerElapsed(profileTime)); 03554 timerFree(profileTime); 03555 03556 return result; 03557 } 03558 03559 /* ---------------------------------------------------------------------- 03560 Perform a complete search on increasing prefixes of the 03561 word graph. 03562 */ 03563 Boolean cmdISearch(int no, char **args) 03564 { 03565 String id = NULL; 03566 ConstraintNet net; 03567 int i; 03568 Lattice lattice = NULL; 03569 Timer profileTime; 03570 03571 int agSize = 1000; 03572 Number agThreshold = -1.0; 03573 Number nonSpecThreshold = 0.0; 03574 03575 char usage[] = 03576 "usage: isearch <wordgraph>\n" 03577 " <agenda-size> (default 1000)\n" 03578 " <agenda-threshold> (default 0.0)\n" 03579 " <nonspec-threshold> (default 0.0)\n"; 03580 03581 if (args == NULL) { 03582 cdgPrintf(CDG_ERROR, "ERROR: argument is NULL\n"); 03583 return FALSE; 03584 } 03585 03586 if (no < 1 || (id = args[0]) == NULL) { 03587 if (inputMostRecentlyCreatedLattice == NULL) { 03588 cdgPrintf(CDG_ERROR, 03589 "ERROR: `isearch' needs a word graph id or a default word graph.\n%s", 03590 usage); 03591 return FALSE; 03592 } 03593 cdgPrintf(CDG_INFO, 03594 "INFO: using most recently created word graph `%s'\n", 03595 inputMostRecentlyCreatedLattice->id); 03596 lattice = inputMostRecentlyCreatedLattice; 03597 } 03598 03599 if (no < 1 || no > 4) { 03600 cdgPrintf(CDG_ERROR, "ERROR: wrong no of parameters\n%s", usage); 03601 return FALSE; 03602 } 03603 03604 for (i = 0; i < no; i++) { 03605 switch (i) { 03606 case 0: 03607 id = args[i]; 03608 if (!(lattice = findLattice(id))) { 03609 cdgPrintf(CDG_ERROR, "ERROR: wordgraph '%s' unknown\n%s", id, usage); 03610 return FALSE; 03611 } 03612 break; 03613 case 1: /* size */ 03614 agSize = atoi(args[i]); 03615 break; 03616 case 2: /* threshold */ 03617 sscanf(args[i], "%lf", &agThreshold); 03618 break; 03619 case 3: /* nonspec-threshold */ 03620 sscanf(args[i], "%lf", &nonSpecThreshold); 03621 break; 03622 default: 03623 cdgPrintf(CDG_ERROR, "ERROR: unknown option '%s'\n%s", args[i], usage); 03624 return FALSE; 03625 } 03626 } 03627 03628 cdgPrintf(CDG_INFO, 03629 "INFO: agenda-size=%d\n" 03630 " agenda-threshold=%4.3e\n" 03631 " nonSpec-threshold=%4.3e\n", 03632 agSize, agThreshold, nonSpecThreshold); 03633 03634 cdgCtrlCAllowed = TRUE; 03635 cdgCtrlCTrapped = FALSE; 03636 03637 profileTime = timerNew(); 03638 net = incSearch(lattice, agSize, agThreshold, nonSpecThreshold); 03639 cdgPrintf(CDG_PROFILE, 03640 "PROFILE: isearch took %lums\n", timerElapsed(profileTime)); 03641 timerFree(profileTime); 03642 03643 cdgCtrlCTrapped = FALSE; 03644 cdgCtrlCAllowed = FALSE; 03645 cnMostRecentlyCreatedNet = net; 03646 03647 if (!net) { 03648 cdgPrintf(CDG_ERROR, "ERROR: invalid net\n"); 03649 return FALSE; 03650 } 03651 hashSet(cdgNets, net->id, net); 03652 03653 return TRUE; 03654 } 03655 03656 /* ---------------------------------------------------------------------- 03657 Sort all levels according to the specified order and 03658 display the new order. 03659 */ 03660 Boolean cmdLevelsort(int no, char **args) 03661 { 03662 if (no != listSize(inputCurrentGrammar->levels)) { 03663 cdgPrintf(CDG_ERROR, 03664 "ERROR: please specify all %d levels\n", 03665 listSize(inputCurrentGrammar->levels)); 03666 return FALSE; 03667 } 03668 03669 if (setLevelSort(args)) { 03670 cdgPrintf(CDG_INFO, "INFO: order of levels: %s\n", getLevelSort()); 03671 return TRUE; 03672 } 03673 03674 return FALSE; 03675 } 03676 03677 /* ---------------------------------------------------------------------- 03678 Set or query hooks. 03679 */ 03680 Boolean cmdHook(int no, char **args) 03681 { 03682 int i; 03683 Hook hook; 03684 int hookNo; 03685 const char *usage = "hook [ on|off|reset | <HookName> [on|off|reset] ]"; 03686 03687 if (args == NULL) { 03688 cdgPrintf(CDG_ERROR, "ERROR: argument is NULL\n"); 03689 return FALSE; 03690 } 03691 03692 if (no > 2) { 03693 cdgPrintf(CDG_ERROR, "ERROR: wrong # args\n" " %s\n", usage); 03694 return FALSE; 03695 } 03696 03697 if (no < 1 || args[0] == NULL) { 03698 cdgPrintf(CDG_DEFAULT, "\n No Name State Count\n"); 03699 cdgPrintf(CDG_DEFAULT, " -----------------------------------------\n"); 03700 for (i = 0; i < vectorSize(hkHooks); i++) { 03701 hook = (Hook) vectorElement(hkHooks, i); 03702 if (!hook) 03703 continue; 03704 03705 cdgPrintf(CDG_DEFAULT, " %02d %-20s %-8s %d\n", 03706 i, hook->name, 03707 (hook->active ? "enabled" : "disabled"), hook->count); 03708 } 03709 cdgPrintf(CDG_DEFAULT, "\n hooking %s.\n\n", 03710 (hkVerbosity & CDG_HOOK ? "enabled" : "disabled")); 03711 } 03712 03713 if (no == 1) { 03714 if (strcmp(args[0], "on") == 0) { 03715 cdgPrintf(CDG_INFO, "INFO: hooking enabled\n"); 03716 hkVerbosity |= CDG_HOOK; 03717 } else if (strcmp(args[0], "off") == 0) { 03718 cdgPrintf(CDG_INFO, "INFO: hooking disabled\n"); 03719 hkVerbosity &= ~CDG_HOOK; 03720 } else if (strcmp(args[0], "reset") == 0) { 03721 cdgPrintf(CDG_INFO, "INFO: resetting counter of all hooks\n"); 03722 for (i = 0; i < vectorSize(hkHooks); i++) { 03723 hook = (Hook) vectorElement(hkHooks, i); 03724 hook->count = 0; 03725 } 03726 } else { 03727 hookNo = hkFindNoOfHook(args[0]); 03728 if (hookNo < 0) { 03729 cdgPrintf(CDG_ERROR, "ERROR: unknown hook `%s'\n", args[0]); 03730 return FALSE; 03731 } 03732 hook = (Hook) vectorElement(hkHooks, hookNo); 03733 hook->active ^= TRUE; 03734 cdgPrintf(CDG_INFO, "INFO: hook `%s' is %s\n", 03735 hook->name, (hook->active ? "enabled" : "disabled")); 03736 } 03737 } 03738 03739 if (no == 2) { 03740 hookNo = hkFindNoOfHook(args[0]); 03741 if (hookNo < 0) { 03742 cdgPrintf(CDG_ERROR, "ERROR: unknown hook `%s'\n", args[0]); 03743 return FALSE; 03744 } 03745 hook = (Hook) vectorElement(hkHooks, hookNo); 03746 03747 if (strcmp(args[1], "on") == 0) { 03748 hook->active = TRUE; 03749 cdgPrintf(CDG_INFO, "INFO: hook `%s' is enabled\n", hook->name); 03750 } else if (strcmp(args[1], "off") == 0) { 03751 hook->active = FALSE; 03752 cdgPrintf(CDG_INFO, "INFO: hook `%s' is disabled\n", hook->name); 03753 } else if (strcmp(args[1], "reset") == 0) { 03754 hook->count = 0; 03755 cdgPrintf(CDG_INFO, "INFO: hook `%s' is reseted\n", hook->name); 03756 } else { 03757 cdgPrintf(CDG_ERROR, "ERROR: unknown option `%s'\n" 03758 " %s\n", args[1], usage); 03759 return FALSE; 03760 } 03761 } 03762 03763 return TRUE; 03764 } 03765 03766 /* ---------------------------------------------------------------------- 03767 Subject the specified net to a guided local search 03768 for global solutions. 03769 */ 03770 Boolean cmdGls(int no, char **args) 03771 { 03772 return (glsCommand(no, args) >= 0); 03773 } 03774 03775 /* ---------------------------------------------------------------------- 03776 Compare parse to annotation. 03777 */ 03778 Boolean cmdVerify(int no, char **args) 03779 { 03780 Parse p = NULL; 03781 AnnoEntry ae = NULL; 03782 String id; 03783 ParseVerification pv; 03784 Lattice lat; 03785 03786 if (no > 0) { 03787 if (!(p = parseFind(args[0]))) { 03788 cdgPrintf(CDG_ERROR, "ERROR: no such Parse, `%s'\n", args[0]); 03789 return FALSE; 03790 } 03791 } else { 03792 if (!(p = parseMostRecentlyCreatedParse)) { 03793 cdgPrintf(CDG_ERROR, "ERROR: no Parse available.\n"); 03794 return FALSE; 03795 } 03796 } 03797 03798 if (no > 1) { 03799 id = strRegister(args[1]); 03800 } else { 03801 id = p->latticeId; 03802 } 03803 03804 if (!(lat = findLattice(id))) { 03805 cdgPrintf(CDG_ERROR, "ERROR: no such lattice.\n"); 03806 return FALSE; 03807 } 03808 03809 if (!(ae = findAnnoForLattice(lat, TRUE))) { 03810 cdgPrintf(CDG_ERROR, "ERROR: no such annotation.\n"); 03811 return FALSE; 03812 } 03813 03814 cdgPrintf(CDG_INFO, "Accuracy of %s:\n", p->id); 03815 pv = parseVerify(p, ae); 03816 writeXmlParseVerification(pv); 03817 parseVerificationDelete(pv); 03818 03819 return TRUE; 03820 } 03821 03822 /* ---------------------------------------------------------------------- 03823 Chunk the specified wordgraph. 03824 */ 03825 Boolean cmdChunk(int no, char **args) 03826 { 03827 Lattice lattice; 03828 int i; 03829 Chunker chunker; 03830 List chunks = NULL; 03831 LexemGraph lg; 03832 Timer profileTime; 03833 int noLattices; 03834 List l; 03835 03836 if (args == NULL) { 03837 cdgPrintf(CDG_ERROR, "ERROR: argument is NULL\n"); 03838 return FALSE; 03839 } 03840 03841 profileTime = timerNew(); 03842 noLattices = 0; 03843 cdgCtrlCAllowed = TRUE; 03844 cdgCtrlCTrapped = FALSE; 03845 03846 for(l = inputCurrentGrammar->lattices; l != NULL; l = listNext(l)) { 03847 lattice = listElement(l); 03848 03849 if (no > 0) { 03850 for (i = 0; i < no && args[i] != NULL; i++) { 03851 if (lattice->id == strRegister(args[i])) { 03852 lg = lgNew(lattice); 03853 if (taggerTag(lg) < 0) { 03854 timerFree(profileTime); 03855 lgDelete(lg); 03856 return FALSE; 03857 } 03858 chunker = chunkerNew(DefaultChunker, lg); 03859 if (!chunker) { 03860 cdgPrintf(CDG_ERROR, "ERROR: chunking of '%s' failed\n", 03861 lattice->id); 03862 timerFree(profileTime); 03863 lgDelete(lg); 03864 return FALSE; 03865 } 03866 chunks = chunkerChunk(chunker); 03867 chunkerPrintChunks(CDG_INFO, chunks); 03868 lgDelete(lg); 03869 chunkerDelete(chunker); 03870 noLattices++; 03871 break; 03872 } 03873 } 03874 } else { 03875 lg = lgNew(lattice); 03876 if (taggerTag(lg) < 0) { 03877 timerFree(profileTime); 03878 lgDelete(lg); 03879 return FALSE; 03880 } 03881 chunker = chunkerNew(DefaultChunker, lg); 03882 if (!chunker) { 03883 cdgPrintf(CDG_ERROR, "ERROR: chunking of '%s' failed\n", lattice->id); 03884 timerFree(profileTime); 03885 lgDelete(lg); 03886 return FALSE; 03887 } 03888 chunks = chunkerChunk(chunker); 03889 chunkerPrintChunks(CDG_INFO, chunks); 03890 lgDelete(lg); 03891 noLattices++; 03892 } 03893 } 03894 cdgPrintf(CDG_PROFILE, "\nPROFILE: chunking %d lattice(s) took %lums\n", 03895 noLattices, timerElapsed(profileTime)); 03896 timerFree(profileTime); 03897 cdgCtrlCTrapped = cdgCtrlCAllowed = FALSE; 03898 03899 return (chunks != NULL); 03900 } 03901 03902 /* ---------------------------------------------------------------------- 03903 Print the help string for the specified CDG command. 03904 */ 03905 Boolean cmdHelp(int no, char **args) 03906 { 03907 int i, j; 03908 03909 if (args == NULL) { 03910 cdgPrintf(CDG_ERROR, "ERROR: argument is NULL\n"); 03911 return FALSE; 03912 } 03913 03914 for (i = 0; interface_commands[i].name != NULL; i++) { 03915 if (no > 0) { 03916 for (j = 0; j < no && args[j] != NULL; j++) { 03917 if (strcmp(interface_commands[i].name, args[j]) == 0) { 03918 cdgPrintf(CDG_DEFAULT, 03919 "%15s %s\n", args[j], interface_commands[i].doc); 03920 break; 03921 } 03922 } 03923 } else { 03924 cdgPrintf(CDG_DEFAULT, 03925 "%15s %s\n", 03926 interface_commands[i].name, interface_commands[i].doc); 03927 } 03928 } 03929 03930 return TRUE; 03931 } 03932 03933 /* ---------------------------------------------------------------------- 03934 Specifies a file to be used for autoloading lexicon items. 03935 03936 The parameter must be string that is used as the file name. The file of 03937 cdg input must be called S.cdg, and the index must be called S.db. 03938 03939 If these files are not in the current working directory they are also 03940 searched in other directories that input was loaded from. 03941 */ 03942 Boolean cmdUseLexicon(int no, char **args) { 03943 String name; 03944 03945 if (no != 1) { 03946 cdgPrintf(CDG_ERROR, "ERROR: `uselexicon' needs one string argument.\n"); 03947 return FALSE; 03948 } 03949 03950 name = strCopy(args[0]); 03951 dbOpen(name); 03952 03953 return TRUE; 03954 } 03955 03956 /* ---------------------------------------------------------------------- 03957 Close the lexicon database. 03958 */ 03959 03960 Boolean cmdCloseDB() 03961 { 03962 return dbClose(); 03963 } 03964 03965 /* ---------------------------------------------------------------------- 03966 Save all parses to a file in Prolog format. 03967 */ 03968 03969 Boolean cmdParses2prolog(int no, char **args) 03970 { 03971 char filename[PATH_MAX]; 03972 FILE *s; 03973 List l, m; 03974 int i = 0; 03975 03976 if (no != 1) { 03977 cdgPrintf(CDG_ERROR, "ERROR: please specify one file name\n"); 03978 return FALSE; 03979 } 03980 03981 realpath(args[0], filename); 03982 s = fopen(filename, "w"); 03983 03984 if (s == NULL) { 03985 cdgPrintf(CDG_ERROR, "ERROR: cannot open %s\n", filename); 03986 return FALSE; 03987 } 03988 /* cdgPrintf(CDG_DEFAULT, "File '%s' successfully opened.\n", cdgFilepath); */ 03989 03990 for (l = m = hashListOfKeys(cdgParses); l != NULL; l = listNext(l)) { 03991 String id = listElement(l); 03992 Parse p = hashGet(cdgParses, id); 03993 03994 writePrologParse(s, p); 03995 i++; 03996 } 03997 listDelete(m); 03998 (void)fclose(s); 03999 04000 cdgPrintf(CDG_INFO, "%i parse(s) written to `%s'\n", i, filename); 04001 04002 return TRUE; 04003 } 04004 04005 /* ---------------------------------------------------------------------- 04006 Save all annotations to a file in Prolog format. 04007 */ 04008 Boolean cmdAnnos2prolog(int no, char **args) 04009 { 04010 char filename[PATH_MAX]; 04011 FILE* s; 04012 List l, m; 04013 int i = 0; 04014 04015 if (no != 1) 04016 { 04017 cdgPrintf(CDG_ERROR, "ERROR: please specify a file name\n"); 04018 return FALSE; 04019 } 04020 04021 realpath(args[0], filename); 04022 s = fopen(filename, "w"); 04023 04024 if (s == NULL) 04025 { 04026 cdgPrintf(CDG_ERROR, "ERROR: cannot open %s\n", filename); 04027 return FALSE; 04028 } 04029 /*cdgPrintf(CDG_DEFAULT, "File '%s' successfully opened.\n", cdgFilepath);*/ 04030 04031 for(l = m = hashListOfKeys(inputCurrentGrammar->annotations); l != NULL; l = listNext(l)) 04032 { 04033 String id = listElement(l); 04034 AnnoEntry ae = hashGet(inputCurrentGrammar->annotations, id); 04035 writePrologAE(s,ae); 04036 i++; 04037 } 04038 listDelete(m); 04039 (void)fclose(s); 04040 04041 cdgPrintf(CDG_INFO,"%i annotation(s) written to `%s'\n",i,filename); 04042 04043 return TRUE; 04044 } 04045 04046 /* ---------------------------------------------------------------------- 04047 Perform chart-based search. 04048 */ 04049 Boolean cmdChart(int no, char **args) { 04050 return chart_search(no, args); 04051 } 04052 04053 /* ---------------------------------------------------------------------- */ 04054 /* -- ENDOFFILE --------------------------------------------------------- */ 04055 04056 /** @} */

CDG 0.95 (20 Oct 2004)