• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  SR_Grammar.h  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 #ifndef __SR_GRAMMAR_H
21 #define __SR_GRAMMAR_H
22 
23 
24 
25 #include "ESR_ReturnCode.h"
26 #include "pstdio.h"
27 #include "ptypes.h"
28 #include "SR_GrammarPrefix.h"
29 #include "SR_NametagDefs.h"
30 #include "SR_Vocabulary.h"
31 #include "SR_AcousticModels.h"
32 #include "SR_Recognizer.h"
33 #include "SR_SemanticResult.h"
34 
35 /* forward decl needed because of SR_Recognizer.h <-> SR_Grammar.h include loop */
36 struct SR_Recognizer_t;
37 
38 /**
39  * @addtogroup SR_GrammarModule SR_Grammar API functions
40  * Contains recognition grammar.
41  *
42  * A grammar consists of a list of rules.
43  *
44  * A rule consists of a list of words and slots. For example:
45  * MY_RULE = "My name is $name" where "name" is a slot
46  *
47  * Words, Nametags may be added or removed from slots.
48  * Upon adding and removing words, the grammar needs to be recompiled for the changes to
49  * take place. However, the original CompiledGrammar remains valid even if compilation never
50  * takes place.
51  *
52  * Two types of slots exist: word slots and nametag slots
53  *
54  * @{
55  */
56 
57 /**
58  * Grammar dispatch function. Used for symantic processing.
59  *
60  * @param functionName Name of function that was invoked
61  * @param argv Argument values passed to function
62  * @param argc Number of arguments passed to function
63  * @param value Dispatch value (specified using SR_GrammarSetDispatchValue)
64  * @param result Result of function operation. Caller passes in this buffer, function fills it.
65  * @param resultSize Size of result buffer. If the passed in buffer was not large enough to hold
66  *                   the result, this value is updated with the required length.
67  */
68 typedef ESR_ReturnCode(*SR_GrammarDispatchFunction)(LCHAR* functionName, LCHAR** argv, size_t argc, void* value, LCHAR* result, size_t* resultSize);
69 
70 /**
71  * Contains recognition grammar.
72  *
73  * A grammar consists of a list of rules.
74  *
75  * A rule consists of a list of words and slots. For example:
76  * MY_RULE = "My name is $name" where "name" is a slot
77  *
78  * Words, Nametags may be added or removed from slots.
79  * Upon adding and removing words, the grammar needs to be recompiled for the changes to
80  * take place. However, the original CompiledGrammar remains valid even if compilation never
81  * takes place.
82  *
83  * Two types of slots exist: word slots and nametag slots
84  */
85 typedef struct SR_Grammar_t
86 {
87   /**
88    * Compiles the grammar.
89    * In the case of a precompiled grammar, the function compiles those portions of the grammar
90    * that were dynamically added since the last compilation.
91    *
92    * @param self SR_Grammar handle
93   * @return ESR_SUCCESS if compilation succeeded, ESR_FATAL_ERROR otherwise.
94    */
95   ESR_ReturnCode(*compile)(struct SR_Grammar_t* self);
96 
97   /**
98   * Saves a compiled grammar to a file.
99   *
100   * @param self SR_Grammar handle
101   * @param filename File to write grammar into
102   * @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_INVALID_STATE if could not save the grammar
103   */
104   ESR_ReturnCode(*save)(struct SR_Grammar_t* self, const LCHAR* filename);
105 
106   /**
107    * Indicates if a transcription is a valid result of a Grammar rule.
108    *
109    * @param self SR_Grammar handle
110    * @param transcription Transcription value
111    * @param result [in/out] Array of semantic results to be populated
112    * @param resultCount [in/out] Length of result array
113   * @return ESR_INVALID_ARGUMENT if self or transcription are null; ESR_INVALID_STATE if an internal error has occured.
114    */
115   ESR_ReturnCode(*checkParse)(struct SR_Grammar_t* self, const LCHAR* transcription, SR_SemanticResult** result, size_t* resultCount);
116 
117   /**
118    * Adds word to rule slot.
119    *
120    * @param self SR_Grammar handle
121    * @param slot Slot name
122    * @param word Word to be added to the slot
123    * @param pronunciation Word pronunciation (optional). Pass NULL to omit.
124    * @param weight value to associate with word when adding to grammar; use to determine cost when parsing
125    * @param tag eScript semantic expression (tag) for the word
126    * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if the vocabulary is missing,
127    * if OSI logging fails; ESR_OUT_OF_MEMORY if word cannot be added to the grammar
128    * (addWords=X is too small); ESR_NOT_SUPPORTED if homonyms are added to the grammar
129    */
130   ESR_ReturnCode(*addWordToSlot)(struct SR_Grammar_t* self, const LCHAR* slot, const LCHAR* word,
131 		const LCHAR* pronunciation, int weight, const LCHAR* tag);
132 
133   /**
134    * Removes all elements from all slots.
135    *
136    * @param self SR_Grammar handle
137    * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if resetting the slots or OSI logging fails
138    */
139   ESR_ReturnCode(*resetAllSlots)(struct SR_Grammar_t* self);
140 
141   /**
142    * Adds nametag to rule slot.
143    *
144    * @param self SR_Grammar handle
145    * @param slot Slot name
146    * @param nametag Nametag to be added to the grammar
147    * @param weight value to associate with nametag when adding to grammar; use to determine cost when parsing
148    * @param tag eScript semantic expression (tag) for the nametag
149    * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if the grammar is active,
150    * if the vocabulary is missing, if OSI logging fails; ESR_OUT_OF_MEMORY if word cannot be added to
151    * the grammar (addWords=X is too small); ESR_NOT_SUPPORTED if homonyms are added to the grammar
152    */
153   ESR_ReturnCode(*addNametagToSlot)(struct SR_Grammar_t* self, const LCHAR* slot,
154     const SR_Nametag* nametag, int weight, const LCHAR* tag);
155 
156   /**
157    * Sets user dispatch function (used for parsed callback, etc)
158    *
159    * @param self SR_Grammar handle
160    * @param name The name of the function which will trigger this callback when encountered during grammar parsing.
161    * @param userData The user data to be referenced in the callback implementation later on.
162    * @param function The dispatch function
163    * @return ESR_INVALID_ARGUMENT if self is null; ESR_SUCCESS
164    */
165   ESR_ReturnCode(*setDispatchFunction)(struct SR_Grammar_t* self, const LCHAR* name, void* userData, SR_GrammarDispatchFunction function);
166 
167   /**
168    * Sets grammar parameter, overriding session defaults.
169    *
170    * @param self SR_Grammar handle
171    * @param key Parameter name
172    * @param value Parameter value
173   * @return ESR_INVALID_ARGUMENT if self is null; ESR_NOT_IMPLEMENTED
174    */
175   ESR_ReturnCode(*setParameter)(struct SR_Grammar_t* self, const LCHAR* key, void* value);
176 
177   /**
178    * Sets grammar parameters.
179    * This is a convenience function.
180    *
181    * @param self SR_Grammar handle
182    * @param key Parameter name
183    * @param value Parameter value
184   * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_RESULT_TYPE if the property is already set and its type is size_t
185    */
186   ESR_ReturnCode(*setSize_tParameter)(struct SR_Grammar_t* self, const LCHAR* key, size_t value);
187 
188   /**
189    * Returns grammar parameter value.
190    *
191    * @param self SR_Grammar handle
192    * @param key Parameter name
193    * @param value Parameter value
194   * @return ESR_INVALID_ARGUMENT if self is null; ESR_NOT_IMPLEMENTED
195    */
196   ESR_ReturnCode(*getParameter)(struct SR_Grammar_t* self, const LCHAR* key, void** value);
197 
198   /**
199    * Return copy of unsigned int grammar parameter.
200    * This is a convenience function.
201    *
202    * @param self SR_Grammar handle
203    * @param key Parameter name
204    * @param value [out] Used to hold the parameter value
205    * @param len [in/out] Length of value argument. If the return code is ESR_BUFFER_OVERFLOW,
206    *            the required length is returned in this variable.
207   * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_RESULT_TYPE if the property type is not size_t; ESR_NO_MATCH_ERROR if property is not set
208    */
209   ESR_ReturnCode(*getSize_tParameter)(struct SR_Grammar_t* self, const LCHAR* key, size_t* value);
210 
211   /**
212    * Configures a vocabulary with the grammar.
213    *
214    * @param self SR_Grammar handle
215    * @param vocabulary The vocabulary to associate with
216   * @return ESR_INVALID_ARGUMENT if self or vocabulary are null
217    */
218   ESR_ReturnCode(*setupVocabulary)(struct SR_Grammar_t *self, SR_Vocabulary *vocabulary);
219 
220   /**
221    * Associates Recognizer with the grammar.
222    *
223    * @param self SR_Grammar handle
224    * @param recognizer The recognizer to associate
225    * @return ESR_INVALID_ARGUMENT if self or recognizer are null
226    */
227   // ESR_ReturnCode(*setupModels)(struct SR_Grammar_t* self, SR_AcousticModels* models);
228   ESR_ReturnCode(*setupRecognizer)(struct SR_Grammar_t* self, struct SR_Recognizer_t* recognizer);
229   /**
230    * Dissociates Recognizer with the grammar.
231    *
232    * @param self SR_Grammar handle
233    * @return ESR_INVALID_ARGUMENT if self is null
234    */
235   ESR_ReturnCode(*unsetupRecognizer)(struct SR_Grammar_t* self);
236 
237   /**
238    * Returns AcousticModels associated with the grammar.
239    *
240    * @param self SR_Grammar handle
241    * @param models Associated models
242   * @return ESR_INVALID_ARGUMENT if self or models are null
243    */
244   // ESR_ReturnCode(*getModels)(struct SR_Grammar_t* self, SR_AcousticModels** models);
245 
246   /**
247    * Destroys a grammar.
248    *
249    * @param self SR_Grammar handle
250   * @return ESR_INVALID_ARGUMENT if self is null, ESR_INVALID_STATE if OSI logging fails
251    */
252   ESR_ReturnCode(*destroy)(struct SR_Grammar_t* self);
253 }
254 SR_Grammar;
255 
256 /**
257  * @name Grammar compilation
258  *
259  * Categories:
260  * - Initialization
261  * - Compile from expressions (not supported by SREC) or load pre-compiled grammars
262  * - Dynamic modification; slots
263  * - Support functions (isExtant, etc)
264  * - Use in recognition; activation
265  *
266  * IMPORTANT NOTE: There are two main approaches to grammar activation in a recognizer.
267  * - 1. Load a pre-compiler grammar setup. This is not just the set of expressions but is also
268  *      an image of the actual model components network that fully describes the recognizer
269  *      task. This type of Grammar can be extended with single arcs at pre-defined points
270  *      called slots.
271  *
272  * - 2. Create a network dynamically from a set of regular expressions.
273  *
274  * SREC supports 1. but not 2. CREC supports 2 but not 1. Both approaches are covered by
275  * this interface. Pre-compiled grammars inherently refer to models. It is therefore
276  * important to ensure consistency of model usage between all activated grammars. This can
277  * be done prior to grammar rule activation in the Recognizer
278  * (see SR_RecognizerCheckGrammarConsistency()).
279  *
280  * A Grammar may consist of one or more rules. Rules are given as expressions (this interface is
281  * independent of the format). A rule may contain other rules. Before a rule can be used in
282  * recognition it must be compiled (or loaded), setup by a recognizer and activated.
283  * -  The Grammar_CompileRule() step combines all sub-rule expressions into a single underlying
284  *    member of Grammar.
285  * -  The Recognizer_ActivateRule() step simply raises a flat to make a compiled rule available
286  *    for recognition.
287  *
288  * Once a Grammar is setup by a recognizer it is not permissible to modify its rules  Thus, in
289  * order to be able to support a combination of a static rule and one that requires changing, it
290  * is most efficient to separate these rules into two Grammar objects.
291  *
292  * NOTE: The modification/setup constraint ensures consistency between the rule definitions
293  * in the Grammar and the setup rules. It would be possible to remove this constraint and
294  * allow rules that had no dependents to be modified while the grammar was setup. This makes
295  * the API freer but also less consistent and more susceptible to error. There would be no
296  * footprint cost with having two grammars in place of one grammar with two rules unless the
297  * rules overlapped. If there was overlap then it might have been possible to minimize the
298  * shared parts
299  * @{
300  */
301 
302 /**
303  * Compiles the grammar.
304  * In the case of a precompiled grammar, the function compiles those portions of the grammar
305  * that were dynamically added since the last compilation.
306  *
307  * @param self SR_Grammar handle
308  * @return ESR_INVALID_ARGUMENT if self is null; ESR_SUCCESS if compilation succeeded, ESR_FATAL_ERROR otherwise.
309  */
310 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarCompile(SR_Grammar* self);
311 /**
312  * @}
313  *
314  * @name Special "Slot"-based Grammar functions
315  *
316  * Slots are points in a pre-compiled grammar where a simple extension of the grammar may
317  * be made. They support the insertion of words or nametags into a pr-defined position in
318  * the Grammar. Slots are first declared in an expression which is compiled and saved for
319  * re-loading. The names of these slots are used in a similar way as rule names.
320  *
321  * @{
322  */
323 /**
324  * Adds word to rule slot.
325  *
326  * @param self SR_Grammar handle
327  * @param slot Slot name
328  * @param word Word to be added to the slot
329  * @param pronunciation Word pronunciation (optional). Pass NULL to omit.
330  * @param weight value to associate with word when adding to grammar; use to determine cost when parsing
331  * @param tag eScript semantic expression for the word. In other words, eScript will execute
332  *            "MEANING=<tag>"
333  * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if the grammar is active,
334  * if the vocabulary is missing, if OSI logging fails; ESR_OUT_OF_MEMORY if word cannot be added to
335  * the grammar (addWords=X is too small); ESR_NOT_SUPPORTED if homonyms are added to the grammar
336  */
337 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarAddWordToSlot(SR_Grammar* self, const LCHAR* slot,
338 																												const LCHAR* word, const LCHAR* pronunciation,
339 																												int weight, const LCHAR* tag);
340 /**
341  * Removes all elements from all slots.
342  *
343  * @param self SR_Grammar handle
344  * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if resetting the slots or
345  * OSI logging fails
346  */
347 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarResetAllSlots(SR_Grammar* self);
348 /**
349  * Adds word to rule slot.
350  *
351  * @param self SR_Grammar handle
352  * @param slot Slot name
353  * @param nametag Nametag to be added to the slot
354  * @param weight value to associate with nametag when adding to grammar; use to determine cost when parsing
355  * @param tag eScript semantic expression (tag) for the nametag
356  * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_STATE if the grammar is active, if the
357  * vocabulary is missing, if OSI logging fails; ESR_OUT_OF_MEMORY if word cannot be added to the
358  * grammar (addWords=X is too small); ESR_NOT_SUPPORTED if homonyms are added to the grammar
359  */
360 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarAddNametagToSlot(SR_Grammar* self, const LCHAR* slot,
361 const struct SR_Nametag_t* nametag, int weight, const LCHAR* tag);
362 /**
363  * @}
364  *
365  * @name Grammar Setup functions
366  *
367  * The Grammar object needs an association with several objects:
368  * - A Grammar object must use one and only one Vocabulary object.
369  * - A Grammar object may use one and only one Nametags object. (The Nametags object can
370  *   however be used by more than one Grammar. A Nametags collection object must be used
371  *   before nametags can be added to Grammar slots.)
372  *
373  * @see Nametags_Add() and associated functions for Nametags management.
374  *
375  * @{
376  */
377 
378 /**
379  * Configures a vocabulary with the grammar.
380  *
381  * @param self SR_Grammar handle
382  * @param vocabulary The vocabulary to associate with
383  * @return ESR_INVALID_ARGUMENT if self or vocabulary are null
384  */
385 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetupVocabulary(SR_Grammar *self, SR_Vocabulary *vocabulary);
386 /**
387  * Associates Grammar with a Recognizer (eg. such that word additions can take place).
388  *
389  * @param self SR_Grammar handle
390  * @param models The recognizer to associate
391  * @return ESR_INVALID_ARGUMENT if self or recognizer are null
392  */
393 // SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetupModels(SR_Grammar* self, SR_AcousticModels* models);
394 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetupRecognizer(SR_Grammar* self, struct SR_Recognizer_t* recognizer);
395 /**
396  * Dissociate Grammar from a Recognizer.
397  *
398  * @param self SR_Grammar handle
399  * @return ESR_INVALID_ARGUMENT if self is null
400  */
401 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarUnsetupRecognizer(SR_Grammar* self);
402 /**
403  * Returns AcousticModels associated with a Grammar.
404  *
405  * @param self SR_Grammar handle
406  * @param models Associated models
407  * @return ESR_INVALID_ARGUMENT if self or models are null
408  */
409 // SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarGetModels(SR_Grammar* self, SR_AcousticModels** models);
410 
411 /**
412  * @}
413  *
414  * @name  Basic Grammar functions
415  *
416  * @{
417  */
418 
419 /**
420  * Create a new grammar.
421  *
422  * @param self SR_Grammar handle
423  */
424 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarCreate(SR_Grammar** self);
425 /**
426  * Destroys a grammar.
427  *
428  * @param self SR_Grammar handle
429  * @return ESR_INVALID_ARGUMENT if self is null, ESR_INVALID_STATE if OSI logging fails
430  */
431 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarDestroy(SR_Grammar* self);
432 /**
433  * Loads a compiled grammar from a file or an image. If the filename has extention .g2g
434  * then it will be loaded as an image. Otherwise, provide only a basename (i.e. without
435  * file extensions), and a set of text-based grammar files will be loaded.
436  *
437  * @param filename File to read grammar from
438  * @param self SR_Grammar handle
439  * @return ESR_INVALID_ARGUMENT if self or the value it points to are null. If the filename load property
440  * (i.e. addWords=X) is unknown; ESR_OUT_OF_MEMORY if system is out of memory; ESR_READ_ERROR if grammar file be read
441  */
442 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarLoad(const LCHAR* filename, SR_Grammar** self);
443 /**
444  * Saves a compiled grammar to a file.
445  *
446  * @param self SR_Grammar handle
447  * @param filename File to write grammar into
448  * @return ESR_INVALID_ARGUMENT if self or filename are null; ESR_INVALID_STATE if could not save the grammar
449  */
450 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSave(SR_Grammar* self, const LCHAR* filename);
451 /**
452  * Sets user dispatch function (used for parsed callback, etc)
453  *
454  * @param self SR_Grammar handle
455  * @param name The name of the function which will trigger this callback when encountered during grammar parsing.
456  * @param userData The user data to be referenced in the callback implementation later on.
457  * @param function The dispatch function
458  * @return ESR_SUCCESS
459  */
460 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetDispatchFunction(SR_Grammar* self, const LCHAR* name, void* userData, SR_GrammarDispatchFunction function);
461 /**
462  * Sets grammar parameter, overriding session defaults.
463  *
464  * @param self SR_Grammar handle
465  * @param key Parameter name
466  * @param value Parameter value
467  * @return ESR_NOT_IMPLEMENTED
468  */
469 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetParameter(SR_Grammar* self, const LCHAR* key, void* value);
470 /**
471  * Sets grammar parameters.
472  * This is a convenience function.
473  *
474  * @param self SR_Grammar handle
475  * @param key Parameter name
476  * @param value Parameter value
477  * @return ESR_INVALID_RESULT_TYPE if the property is already set and its type is size_t
478  */
479 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarSetSize_tParameter(SR_Grammar* self, const LCHAR* key, size_t value);
480 /**
481  * Returns grammar parameter value.
482  *
483  * @param self SR_Grammar handle
484  * @param key Parameter name
485  * @param value Parameter value
486  * @return ESR_NOT_IMPLEMENTED
487  */
488 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarGetParameter(SR_Grammar* self, const LCHAR* key, void** value);
489 /**
490  * Return copy of unsigned int grammar parameter.
491  * This is a convenience function.
492  *
493  * @param self SR_Grammar handle
494  * @param key Parameter name
495  * @param value [out] Used to hold the parameter value
496  * @return ESR_INVALID_ARGUMENT if self is null; ESR_INVALID_RESULT_TYPE if the property type is not size_t; ESR_NO_MATCH_ERROR if property is not set
497  */
498 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarGetSize_tParameter(SR_Grammar* self, const LCHAR* key, size_t* value);
499 /**
500  * Checks if transcription is parsable by the grammar.
501  *
502  * @param self SR_Grammar handle
503  * @param transcription transcription to be checked
504  * @param result should be NULL
505  * @param resultCount used to return the number of valid parses
506  * @return ESR_INVALID_ARGUMENT if self, transcription are null; ESR_INVALID_STATE if an internal error has occured.
507  */
508 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarCheckParse(SR_Grammar* self, const LCHAR* transcription, SR_SemanticResult** result, size_t* resultCount);
509 /**
510  * @}
511  */
512 
513 /**
514  * @}
515  */
516 
517 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarAllowOnly(SR_Grammar* self, const char* transcription);
518 SREC_GRAMMAR_API ESR_ReturnCode SR_GrammarAllowAll(SR_Grammar* self);
519 
520 #endif /* __SR_GRAMMAR_H */
521