/// <summary> /// Creates the grammar. /// </summary> /// <returns>The initial node for the grammar.</returns> protected override GrammarNode CreateGrammar() { GrammarNode initialNode = null; GrammarNode finalNode = null; // first pass create the FST nodes int maxNodeId = CreateNodes(_path); // create the final node: finalNode = CreateGrammarNode(++maxNodeId, IDictionary.SilenceSpelling); finalNode.SetFinalNode(true); // replace each word node with a pair of nodes, which // consists of the word node and a new dummy end node, which is // for adding null or backoff transitions maxNodeId = ExpandWordNodes(maxNodeId); ExtendedStreamTokenizer tok = new ExtendedStreamTokenizer(_path, true); // Second pass, add all of the arcs while (!tok.IsEOF()) { String token; tok.Skipwhite(); token = tok.GetString(); // System.out.println(token); if (token == null) { break; } else if (token.Equals("I")) { Debug.Assert(initialNode == null); int initialID = tok.GetInt("initial ID"); String nodeName = "G" + initialID; // TODO: FlatLinguist requires the initial grammar node // to contain a single silence. We'll do that for now, // but once the FlatLinguist is fixed, this should be // returned to its former method of creating an empty // initial grammar node // initialNode = createGrammarNode(initialID, false); initialNode = CreateGrammarNode(initialID, IDictionary.SilenceSpelling); _nodes.Put(nodeName, initialNode); // optionally add a silence node if (_addInitialSilenceNode) { GrammarNode silenceNode = CreateGrammarNode(++maxNodeId, IDictionary.SilenceSpelling); initialNode.Add(silenceNode, LogMath.LogOne); silenceNode.Add(initialNode, LogMath.LogOne); } } else if (token.Equals("T")) { int thisID = tok.GetInt("this id"); int nextID = tok.GetInt("next id"); GrammarNode thisNode = Get(thisID); GrammarNode nextNode = Get(nextID); // if the source node is an FSTGrammarNode, we want // to join the endNode to the destination node if (HasEndNode(thisNode)) { thisNode = GetEndNode(thisNode); } float lnProb = 0f; // negative natural log String output = tok.GetString(); if (output == null || output.Equals(",")) { // these are epsilon (meaning backoff) transitions if (output != null && output.Equals(",")) { tok.GetString(); // skip the word lnProb = tok.GetFloat("probability"); } // if the destination node has been expanded // we actually want to add the backoff transition // to the endNode if (HasEndNode(nextNode)) { nextNode = GetEndNode(nextNode); } } else { String word = tok.GetString(); // skip words lnProb = tok.GetFloat("probability"); if (_ignoreUnknownTransitions && word.Equals("<unknown>")) { continue; } /* * System.out.println(nextNode + ": " + output); */ Debug.Assert(HasWord(nextNode)); } thisNode.Add(nextNode, ConvertProbability(lnProb)); } else if (token.Equals("F")) { int thisID = tok.GetInt("this id"); float lnProb = tok.GetFloat("probability"); GrammarNode thisNode = Get(thisID); GrammarNode nextNode = finalNode; if (HasEndNode(thisNode)) { thisNode = GetEndNode(thisNode); } thisNode.Add(nextNode, ConvertProbability(lnProb)); } } tok.Close(); Debug.Assert(initialNode != null); return(initialNode); }
/** * Determines if the given node has an end node associated with it. * * @param node the node of interest * @return <code>true</code> if the given node has an end node. */ private bool HasEndNode(GrammarNode node) { return(_expandedNodes.Contains(node)); }
/** * Retrieves the end node associated with the given node * * @param node the node of interest * @return the ending node or null if no end node is available */ private GrammarNode GetEndNode(GrammarNode node) { GrammarArc[] arcs = node.GetSuccessors(); Debug.Assert(arcs != null && arcs.Length > 0); return(arcs[0].GrammarNode); }
/** * Determines if the node has a word * * @param node the grammar node of interest * @return true if the node has a word */ private bool HasWord(GrammarNode node) { return(node.GetNumAlternatives() > 0); }
/** * /// Given a node, returns a GDL shape for the node * * /// @param node the node * /// @return a gdl shape for the node */ string GetGDLShape(GrammarNode node) { return(node.IsEmpty ? "circle" : "box"); }
/** * /// Given a node, returns a GDL Label for the node * * /// @param node the node * /// @return a gdl label for the node */ string GetGDLLabel(GrammarNode node) { string label = node.IsEmpty ? "" : node.GetWord().Spelling; return("\"" + label + "\""); }
/** * /// Gvien a node, return a GDL ID for the node * * /// @param node the node * /// @return the GDL id */ string GetGDLID(GrammarNode node) { return("\"" + node.ID + "\""); }
/// <summary> /// Returns a new GrammarNode with the given single word. If the word is not in the dictionary, an empty node is /// created. The grammar id is automatically assigned /// </summary> /// <param name="word">the word for this grammar node</param> /// <returns></returns> protected GrammarNode CreateGrammarNode(String word) { GrammarNode node = CreateGrammarNode(_maxIdentity + 1, word); return(node); }