Initial import to Tizen
[profile/ivi/sphinxbase.git] / src / libsphinxbase / lm / jsgf_parser.y
1 /* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 2007 Carnegie Mellon University.  All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 %{
38 #include <stdio.h>
39 #include <string.h>
40
41 #include <sphinxbase/hash_table.h>
42 #include <sphinxbase/ckd_alloc.h>
43 #include <sphinxbase/err.h>
44
45 #include "jsgf_internal.h"
46 #include "jsgf_parser.h"
47 #include "jsgf_scanner.h"
48
49 /* Suppress warnings from generated code */
50 #if defined _MSC_VER
51 #pragma warning(disable: 4273)
52 #endif
53
54 void yyerror(yyscan_t lex, jsgf_t *jsgf, const char *s);
55
56 %}
57
58 %pure-parser
59 %lex-param { yyscan_t yyscanner }
60 %parse-param { yyscan_t yyscanner }
61 %parse-param { jsgf_t *jsgf }
62
63 %union {
64        char *name;
65        float weight;
66        jsgf_rule_t *rule;
67        jsgf_rhs_t *rhs;
68        jsgf_atom_t *atom;
69 }
70
71 %token           HEADER GRAMMAR IMPORT PUBLIC
72 %token <name>    TOKEN RULENAME TAG
73 %token <weight>  WEIGHT
74 %type  <atom>    rule_atom rule_item tagged_rule_item
75 %type  <rhs>     rule_expansion alternate_list
76 %type  <name>    grammar_header
77 %type  <rule>    rule_group rule_optional
78 %%
79
80 grammar: header
81         | header rule_list
82         | header import_header rule_list
83         ;
84
85 header: jsgf_header grammar_header { jsgf->name = $2; }
86         ;
87
88 jsgf_header: HEADER ';'
89         | HEADER TOKEN ';' { jsgf->version = $2; }
90         | HEADER TOKEN TOKEN ';' { jsgf->version = $2; jsgf->charset = $3; }
91         | HEADER TOKEN TOKEN TOKEN ';' { jsgf->version = $2; jsgf->charset = $3;
92                                          jsgf->locale = $4; }
93         ;
94
95 grammar_header: GRAMMAR TOKEN ';' { $$ = $2; }
96         ;
97
98 import_header: import_statement
99         | import_header import_statement
100         ;
101
102 import_statement: IMPORT RULENAME ';' { jsgf_import_rule(jsgf, $2); ckd_free($2); }
103         ;
104
105 rule_list: rule
106         | rule_list rule
107         ;
108
109 rule: RULENAME '=' alternate_list ';' { jsgf_define_rule(jsgf, $1, $3, 0); ckd_free($1); }
110 | PUBLIC RULENAME '=' alternate_list ';'  { jsgf_define_rule(jsgf, $2, $4, 1); ckd_free($2); }
111         ;
112
113 alternate_list: rule_expansion { $$ = $1; $$->atoms = glist_reverse($$->atoms); }
114         | alternate_list '|' rule_expansion { $$ = $3;
115                                               $$->atoms = glist_reverse($$->atoms);
116                                               $$->alt = $1; }
117         ;
118
119 rule_expansion: tagged_rule_item { $$ = ckd_calloc(1, sizeof(*$$));
120                                    $$->atoms = glist_add_ptr($$->atoms, $1); }
121         | rule_expansion tagged_rule_item { $$ = $1;
122                                             $$->atoms = glist_add_ptr($$->atoms, $2); }
123         ;
124
125 tagged_rule_item: rule_item
126         | tagged_rule_item TAG { $$ = $1;
127                                  $$->tags = glist_add_ptr($$->tags, $2); }
128         ;
129
130 rule_item: rule_atom
131         | WEIGHT rule_atom { $$ = $2; $$->weight = $1; }
132         ;
133
134 rule_group: '(' alternate_list ')' { $$ = jsgf_define_rule(jsgf, NULL, $2, 0); }
135         ;
136
137 rule_optional: '[' alternate_list ']' { $$ = jsgf_optional_new(jsgf, $2); }
138         ;
139
140 rule_atom: TOKEN { $$ = jsgf_atom_new($1, 1.0); ckd_free($1); }
141         | RULENAME { $$ = jsgf_atom_new($1, 1.0); ckd_free($1); }
142         | rule_group { $$ = jsgf_atom_new($1->name, 1.0); }
143         | rule_optional { $$ = jsgf_atom_new($1->name, 1.0); }
144         | rule_atom '*' { $$ = jsgf_kleene_new(jsgf, $1, 0); }
145         | rule_atom '+' { $$ = jsgf_kleene_new(jsgf, $1, 1); }
146         ;
147
148 %%
149
150 void
151 yyerror(yyscan_t lex, jsgf_t *jsgf, const char *s)
152 {
153     fprintf(stderr, "ERROR: %s\n", s);
154 }