There are several utility programs that will assist you in evaluating grammars that you write:
The boy saw the dog. The dog saw the boy. The cat saw the dog. He saw the dog.
and we write the following simple grammar (see writing grammar files):
;; saw.bnf ;; <s> = <np> <vp> . <vp> = <v> <np> . <np> = <det> <n> | <pro> . ; lexicon <det> = the . <n> = dog | boy | cat . <pro> = he . <v> = saw .
After compiling this grammar using vtbnfc.exe we want to examine what strings the grammar accepts. Using fsgenum.exe (the details will be explained shortly) we see that it generates the following:
As we can now see, the grammar overgenerates--- it accepts a string that is not in the language--- the dog saw he. We can now rewrite the grammar to prevent this string from being accepted. To give a more practical example, rules that allow for the acceptance of twelve hundred dollars might also contribute to the acceptance of the ill-formed four thousand twelve hundred dollars. Overgeneration is a common error in writing complex grammars and this tool is a useful debugging aid.
fsgenum [options] fsg-filenameThe available options are:
;; np.bnf ;; <np> = <det> <adj>* <n>. ; lexicon <adj> = old . <det> = the . <n> = dog .
fsgenum np.fsg and fsgenum -f np.fsg both produce the following output:
the dog the old dogfsgenum -f -l 5 np.fsg produces the output:
the dog the old dog the old old dog the old old old dog the old old old old dog
fsgtest np.fsgAfter issuing this command a user can type in a string followed by the enter key. (However, it should be noted that the program does not produce a prompt.) If the entered string is accepted by np.fsg the string will be echoed. If it is rejected the string is echoed with a preceding asterisk. This is illustrated in the following example (where the user input is in bold).
fsgtest np.fsg the dog the dog the old * the old the old dog the old dog [ctrl-c] The external process was cancelled by a Ctrl+Break or another process.A set of test strings can be input to this program by using file redirection. For example, suppose we have a currency grammar (compiled as currency.fsg) that we would like to test. We have a file, good-set, containing strings we would like the grammar to accept:
twelve hundred dollars four thousand two hundred and eleven dollars a dollar fifty a dollar and a half one and a half dollarsWe also have a file, bad-set, of ill-formed strings that we want the grammar to reject:
four thousand twelve hundred dollars four dollars fifty one dollar and a halfWe can test good-set by using the command:
fsgtest currency.fsg < good-setwhich results in the following output:
twelve hundred dollars four thousand two hundred and eleven dollars a dollar fifty a dollar and a half one and a half dollarsWe can test bad-set by using
fsgtest currency.fsg < bad-setwhich results in the following output:
* four thousand twelve hundred dollars * four dollars fifty * one dollar and a half
fsgtest [options] fsg-filenameThe available options are:
fsgtest -p np.fsg the dog 0.50029 the dog the old ******* the old the old dog 0.25029 the old dog [ctrl-c] The external process was cancelled by a Ctrl+Break or another process.To illustrate the use of annotations we compile the following bnf file to produce np2.fsg:
;; np.bnf ;; <np> = <det> <adj>* <n>. ; lexicon <adj> = old:"adjective" . <det> = the:"determiner" . <n> = dog:"noun" .
Now we use fsgtest with the -a option:
fsgtest -a np2.fsg the dog the:"determiner" dog:"noun" the old the:"determiner" old:"adjective" the old dog the:"determiner" old:"adjective" dog:"noun" [ctrl-c] The external process was cancelled by a Ctrl+Break or another process.
fsgtest np.fsg --- fsg np.fsg --- state 0 the -> state 1 p=1.00 state 1 dog -> state * p=0.50 old -> state 1 p=0.50 state *This shows that the grammar has three states (state 0, state 1, and state *). There is only one transition from state 0. It accepts the word "the" and goes to state 1. If you are in state 0 the probability of taking this transition is 1.00 since it is the only transition. State 1 has two transitions. The first transition accepts the word "dog" and goes to the final state, state *. The second transition accepts the word "old" and loops back to state 1. Since there are two transition out of state 1, the local probability of both of these transitions is 0.50.
fsgprint [options] fsg-filenameThe available options are: