47 #include "jsgf_parser.h"
48 #include "jsgf_scanner.h"
50 int yyparse (yyscan_t yyscanner,
jsgf_t *jsgf);
60 jsgf_atom_new(
char *name,
float weight)
101 #if !defined(_WIN32_WCE)
102 if ((jsgf_path = getenv(
"JSGF_PATH")) != NULL) {
108 while ((c = strchr(word,
':'))) {
130 if (jsgf->
parent == NULL) {
146 for (gn = jsgf->
searchpath; gn; gn = gnode_next(gn))
149 for (gn = jsgf->
links; gn; gn = gnode_next(gn))
168 jsgf_rhs_free(rhs->
alt);
169 for (gn = rhs->
atoms; gn; gn = gnode_next(gn))
189 rule = jsgf_define_rule(jsgf, NULL, rhs, 0);
190 rule_atom = jsgf_atom_new(rule->
name, 1.0);
196 return jsgf_atom_new(rule->
name, 1.0);
206 return jsgf_define_rule(jsgf, NULL, rhs, 0);
222 extract_grammar_name(
char *rule_name)
226 if ((dot_pos = strrchr(grammar_name + 1,
'.')) == NULL) {
235 jsgf_fullname(
jsgf_t *jsgf,
const char *name)
240 if (strchr(name + 1,
'.'))
245 sprintf(fullname,
"<%s.%s", jsgf->
name, name + 1);
250 jsgf_fullname_from_rule(
jsgf_rule_t *rule,
const char *name)
252 char *fullname, *grammar_name;
255 if (strchr(name + 1,
'.'))
259 if ((grammar_name = extract_grammar_name(rule->
name)) == NULL)
261 fullname =
ckd_malloc(strlen(grammar_name) + strlen(name) + 4);
262 sprintf(fullname,
"<%s.%s", grammar_name, name + 1);
271 importname2rulename(
char *importname)
275 char *secondlast_dotpos;
277 if ((last_dotpos = strrchr(rulename+1,
'.')) != NULL) {
279 if ((secondlast_dotpos = strrchr(rulename+1,
'.')) != NULL) {
281 *secondlast_dotpos=
'<';
282 secondlast_dotpos =
ckd_salloc(secondlast_dotpos);
284 return secondlast_dotpos;
304 lastnode = rule->
entry;
307 for (gn = rhs->
atoms; gn; gn = gnode_next(gn)) {
309 if (jsgf_atom_is_rule(atom)) {
316 if (0 == strcmp(atom->
name,
"<NULL>")) {
318 jsgf_add_link(grammar, atom,
319 lastnode, grammar->
nstate);
320 lastnode = grammar->
nstate;
324 else if (0 == strcmp(atom->
name,
"<VOID>")) {
329 fullname = jsgf_fullname_from_rule(rule, atom->
name);
331 E_ERROR(
"Undefined rule in RHS: %s\n", fullname);
338 for (subnode = grammar->
rulestack; subnode; subnode = gnode_next(subnode))
339 if (
gnode_ptr(subnode) == (
void *)subrule)
341 if (subnode != NULL) {
343 if (gnode_next(gn) != NULL) {
344 E_ERROR(
"Only right-recursion is permitted (in %s.%s)\n",
349 E_INFO(
"Right recursion %s %d => %d\n", atom->
name, lastnode, subrule->
entry);
350 jsgf_add_link(grammar, atom, lastnode, subrule->
entry);
354 if (expand_rule(grammar, subrule) == -1)
357 jsgf_add_link(grammar, atom,
358 lastnode, subrule->
entry);
359 lastnode = subrule->
exit;
364 jsgf_add_link(grammar, atom,
365 lastnode, grammar->
nstate);
366 lastnode = grammar->
nstate;
385 for (rhs = rule->
rhs; rhs; rhs = rhs->
alt) {
394 if (norm == 0) norm = 1;
395 for (rhs = rule->
rhs; rhs; rhs = rhs->
alt) {
402 lastnode = expand_rhs(grammar, rule, rhs);
403 if (lastnode == -1) {
407 jsgf_add_link(grammar, NULL, lastnode, rule->
exit);
446 logmath_t *lmath, float32 lw,
int do_closure)
453 for (gn = grammar->
links; gn; gn = gnode_next(gn)) {
457 grammar->
links = NULL;
460 expand_rule(grammar, rule);
462 fsg = fsg_model_init(rule->
name, lmath, lw, grammar->
nstate);
466 for (gn = grammar->
links; gn; gn = gnode_next(gn)) {
470 if (jsgf_atom_is_rule(link->
atom)) {
471 fsg_model_null_trans_add(fsg, link->
from, link->
to,
475 int wid = fsg_model_word_add(fsg, link->
atom->
name);
476 fsg_model_trans_add(fsg, link->
from, link->
to,
481 fsg_model_null_trans_add(fsg, link->
from, link->
to, 0);
485 nulls = fsg_model_null_trans_closure(fsg, NULL);
496 return jsgf_build_fsg_internal(grammar, rule, lmath, lw, TRUE);
503 return jsgf_build_fsg_internal(grammar, rule, lmath, lw, FALSE);
515 fsg_model_write(fsg, outfh);
531 sprintf(name,
"<%s.g%05d>", jsgf->
name, hash_table_inuse(jsgf->
rules));
536 newname = jsgf_fullname(jsgf, name);
546 E_INFO(
"Defined rule: %s%s\n",
547 rule->
public ?
"PUBLIC " :
"",
550 if (val != (
void *)rule) {
551 E_WARN(
"Multiply defined symbol: %s\n", name);
570 jsgf_rhs_free(rule->
rhs);
579 path_list_search(
glist_t paths,
char *path)
583 for (gn = paths; gn; gn = gnode_next(gn)) {
588 tmp = fopen(fullpath,
"r");
600 jsgf_import_rule(
jsgf_t *jsgf,
char *name)
602 char *c, *path, *newpath;
603 size_t namelen, packlen;
609 namelen = strlen(name);
611 strcpy(path, name + 1);
613 c = strrchr(path,
'.');
615 E_ERROR(
"Imported rule is not qualified: %s\n", name);
623 import_all = (strlen(name) > 2 && 0 == strcmp(name + namelen - 3,
".*>"));
626 for (c = path; *c; ++c)
627 if (*c ==
'.') *c =
'/';
628 strcat(path,
".gram");
629 newpath = path_list_search(jsgf->
searchpath, path);
635 E_INFO(
"Importing %s from %s to %s\n", name, path, jsgf->
name);
641 E_INFO(
"Already imported %s\n", path);
649 if (val != (
void *)imp) {
650 E_WARN(
"Multiply imported file: %s\n", path);
661 char *rule_name = importname2rulename(name);
665 rule_matches = !strncmp(rule_name, rule->
name, packlen + 1);
669 rule_matches = !strcmp(rule_name, rule->
name);
672 if (rule->
public && rule_matches) {
677 c = strrchr(rule->
name,
'.');
679 newname = jsgf_fullname(jsgf, c);
681 E_INFO(
"Imported %s\n", newname);
683 jsgf_rule_retain(rule));
684 if (val != (
void *)rule) {
685 E_WARN(
"Multiply defined symbol: %s\n", newname);
706 yylex_init(&yyscanner);
707 if (filename == NULL) {
708 yyset_in(stdin, yyscanner);
711 in = fopen(filename,
"r");
713 fprintf(stderr,
"Failed to open %s for parsing: %s\n",
714 filename, strerror(errno));
717 yyset_in(in, yyscanner);
721 yyrv = yyparse(yyscanner, jsgf);
723 fprintf(stderr,
"JSGF parse of %s failed\n",
724 filename ? filename :
"(stdin)");
726 yylex_destroy(yyscanner);
731 yylex_destroy(yyscanner);