jsgfgrammar.java

来自「It is the Speech recognition software. 」· Java 代码 · 共 814 行 · 第 1/2 页

JAVA
814
字号
                throw new GrammarException("Can't resolve rule: "                        + ruleName.getRuleName());            }            GrammarGraph ruleResult = parseRule(rule);            if (result != ruleResult) {                result.getStartNode().add(ruleResult.getStartNode(), 0.0f);                ruleResult.getEndNode().add(result.getEndNode(), 0.0f);            }        }        ruleStack.pop();        return result;    }    /**     * Parses the given RuleCount into a network of GrammarNodes.     *      * @param ruleCount     *                the RuleCount object to parse     *      * @return a grammar graph     */    private GrammarGraph parseRuleCount(RuleCount ruleCount)            throws GrammarException {        debugPrintln("parseRuleCount: " + ruleCount);        GrammarGraph result = new GrammarGraph();        int count = ruleCount.getCount();        GrammarGraph newNodes = parseRule(ruleCount.getRule());        result.getStartNode().add(newNodes.getStartNode(), 0.0f);        newNodes.getEndNode().add(result.getEndNode(), 0.0f);        // if this is optional, add a bypass arc        if (count == RuleCount.ZERO_OR_MORE || count == RuleCount.OPTIONAL) {            result.getStartNode().add(result.getEndNode(), 0.0f);        }        // if this can possibly occur more than once, add a loopback        if (count == RuleCount.ONCE_OR_MORE || count ==RuleCount.ZERO_OR_MORE) {            newNodes.getEndNode().add(newNodes.getStartNode(), 0.0f);        }        return result;    }    /**     * Parses the given RuleAlternatives into a network of GrammarNodes.     *      * @param ruleAlternatives     *                the RuleAlternatives to parse     *      * @return a grammar graph     */    private GrammarGraph parseRuleAlternatives(RuleAlternatives ruleAlternatives)            throws GrammarException {        debugPrintln("parseRuleAlternatives: " + ruleAlternatives.toString());        GrammarGraph result = new GrammarGraph();        Rule[] rules = ruleAlternatives.getRules();        float[] weights = ruleAlternatives.getWeights();        normalizeWeights(weights);        // expand each alternative, and connect them in parallel        for (int i = 0; i < rules.length; i++) {            Rule rule = rules[i];            float weight = 0.0f;            if (weights != null) {                weight = weights[i];            }            debugPrintln("Alternative: " + rule.toString());            GrammarGraph newNodes = parseRule(rule);            result.getStartNode().add(newNodes.getStartNode(), weight);            newNodes.getEndNode().add(result.getEndNode(), 0.0f);        }        return result;    }    /**     * Normalize the weights. The weights should always be zero or greater. We     * need to convert the weights to a log probability.     *      * @param weights     *                the weights to normalize     */    private void normalizeWeights(float[] weights) {        if (weights != null) {            double sum = 0.0;            for (int i = 0; i < weights.length; i++) {                if (weights[i] < 0) {                    throw new IllegalArgumentException("negative weight");                }                sum += weights[i];            }            for (int i = 0; i < weights.length; i++) {                if (sum == 0.0f) {                    weights[i] = LogMath.getLogZero();                } else {                    weights[i] = logMath.linearToLog(weights[i] / sum);                }            }        }    }    /**     * Parses the given RuleSequence into a network of GrammarNodes.     *      * @param ruleSequence     *                the RuleSequence to parse     *      * @return the first and last GrammarNodes of the network     */    private GrammarGraph parseRuleSequence(RuleSequence ruleSequence)            throws GrammarException {        GrammarNode startNode = null;        GrammarNode endNode = null;        debugPrintln("parseRuleSequence: " + ruleSequence);        Rule[] rules = ruleSequence.getRules();        GrammarNode lastGrammarNode = null;        // expand and connect each rule in the sequence serially        for (int i = 0; i < rules.length; i++) {            Rule rule = rules[i];            GrammarGraph newNodes = parseRule(rule);            // first node            if (i == 0) {                startNode = newNodes.getStartNode();            }            // last node            if (i == (rules.length - 1)) {                endNode = newNodes.getEndNode();            }            if (i > 0) {                lastGrammarNode.add(newNodes.getStartNode(), 0.0f);            }            lastGrammarNode = newNodes.getEndNode();        }        return new GrammarGraph(startNode, endNode);    }    /**     * Parses the given RuleTag into a network GrammarNodes.     *      * @param ruleTag     *                the RuleTag to parse     *      * @return the first and last GrammarNodes of the network     */    private GrammarGraph parseRuleTag(RuleTag ruleTag) throws GrammarException {        debugPrintln("parseRuleTag: " + ruleTag);        Rule rule = ruleTag.getRule();        return parseRule(rule);    }    /**     * Creates a GrammarNode with the word in the given RuleToken.     *      * @param ruleToken     *                the RuleToken that contains the word     *      * @return a GrammarNode with the word in the given RuleToken     */    private GrammarGraph parseRuleToken(RuleToken ruleToken) {        GrammarNode node = createGrammarNode(ruleToken.getText());        return new GrammarGraph(node, node);    }    /**     * Dumps out a grammar exception     *      * @param ge     *                the grammar exception     *       */    private void dumpGrammarException(GrammarException ge) {        System.out.println("Grammar exception " + ge);        GrammarSyntaxDetail[] gsd = ge.getDetails();        if (gsd != null) {            for (int i = 0; i < gsd.length; i++) {                System.out.println("Grammar Name: " + gsd[i].grammarName);                System.out.println("Grammar Loc : " + gsd[i].grammarLocation);                System.out.println("Import Name : " + gsd[i].importName);                System.out.println("Line number : " + gsd[i].lineNumber);                System.out.println("char number : " + gsd[i].charNumber);                System.out.println("Rule name   : " + gsd[i].ruleName);                System.out.println("Message     : " + gsd[i].message);            }        }    }    /**     *  Commit changes to all loaded grammars and all changes of     *  grammar since the last commitChange     */    public void commitChanges() throws IOException {        try {            if (loadGrammar) {                recognizer = new BaseRecognizer();                recognizer.allocate();                ruleGrammar = recognizer.loadJSGF(baseURL, grammarName);                ruleGrammar.setEnabled(true);                loadGrammar = false;            }            recognizer.commitChanges();            ruleStack = new RuleStack();            newGrammar();            firstNode = createGrammarNode("<sil>");            GrammarNode finalNode = createGrammarNode("<sil>");            finalNode.setFinalNode(true);            // go through each rule and create a network of GrammarNodes            // for each of them            String[] ruleNames = ruleGrammar.listRuleNames();            for (int i = 0; i < ruleNames.length; i++) {                String ruleName = ruleNames[i];                if (ruleGrammar.isRulePublic(ruleName)) {                    String fullName = getFullRuleName(ruleName);                    GrammarGraph publicRuleGraph = new GrammarGraph();                    ruleStack.push(fullName, publicRuleGraph);                    Rule rule = ruleGrammar.getRule(ruleName);                    GrammarGraph graph = parseRule(rule);                    ruleStack.pop();                    firstNode.add(publicRuleGraph.getStartNode(), 0.0f);                    publicRuleGraph.getEndNode().add(finalNode, 0.0f);                    publicRuleGraph.getStartNode().add(                                graph.getStartNode(), 0.0f);                    graph.getEndNode().add( publicRuleGraph.getEndNode(), 0.0f);                }            }            postProcessGrammar();        } catch (EngineException ee) {            // ee.printStackTrace();            throw new IOException(ee.toString());        } catch (GrammarException ge) {            // ge.printStackTrace();            dumpGrammarException(ge);            throw new IOException("GrammarException: " + ge);        } catch (MalformedURLException mue) {            throw new IOException("bad base grammar url " + baseURL + " "                    + mue);        }    }    /**     * Gets the fully resolved rule name     *     * @param ruleName the partial name     * @return the fully resovled name     *     * @throws GrammarException      */    private String getFullRuleName(String ruleName) throws GrammarException {        RuleName rname = ruleGrammar.resolve(new RuleName(ruleName));        return rname.getRuleName();    }    /**     * Debugging println     *      * @param message     *                the message to optionally print     */    private void debugPrintln(String message) {        if (false) {            System.out.println(message);        }    }    /**     * Dumps interesting things about this grammar     */    private void dumpGrammar() {        System.out.println("Imported rules { ");        RuleName[] imports = ruleGrammar.listImports();        for (int i = 0; i < imports.length; i++) {            System.out                    .println("  Import " + i + " " + imports[i].getRuleName());        }        System.out.println("}");        System.out.println("Rulenames { ");        String[] names = ruleGrammar.listRuleNames();        for (int i = 0; i < names.length; i++) {            System.out.println("  Name " + i + " " + names[i]);        }        System.out.println("}");    }    /**     * Represents a graph of grammar nodes. A grammar graph has a single     * starting node and a single ending node     */    class GrammarGraph {        private GrammarNode startNode;        private GrammarNode endNode;        /**         * Creates a grammar graph with the given nodes         *          * @param startNode         *                the staring node of the graph         * @param endNode         *                the ending node of the graph         */        GrammarGraph(GrammarNode startNode, GrammarNode endNode) {            this.startNode = startNode;            this.endNode = endNode;        }        /**         * Creates a graph with non-word nodes for the start and ending nodes         */        GrammarGraph() {            startNode = createGrammarNode(false);            endNode = createGrammarNode(false);        }        /**         * Gets the starting node         *          * @return the starting node for the graph         */        GrammarNode getStartNode() {            return startNode;        }        /**         * Gets the ending node         *          * @return the ending node for the graph         */        GrammarNode getEndNode() {            return endNode;        }    }    /**     * Manages a stack of grammar graphs that can be accessed by grammar name     */    class RuleStack {        private List stack;        private HashMap map;        /**         * Creates a name stack         */        public RuleStack() {            clear();        }        /**         * Pushes the grammar graph on the stack         */        public void push(String name, GrammarGraph g) {            stack.add(0, name);            map.put(name, g);        }        /**         * remove the top graph on the stack         */        public void pop() {            map.remove(stack.remove(0));        }        /**         * Checks to see if the stack contains a graph with the given name         *         * @param name  the graph name         * @return the grammar graph associated with the name if found,         * otherwise null         */        public GrammarGraph contains(String name) {            if (stack.contains(name)) {                return (GrammarGraph) (GrammarGraph) map.get(name);            } else {                return null;            }        }        /**         * Clears this name stack         */        public void clear() {            stack = new LinkedList();            map = new HashMap();        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?