GrammarChecker.java :  » XML » jvxml-0.7.2 » org » jvoicexml » implementation » grammar » Java Open Source

Java Open Source » XML » jvxml 0.7.2 
jvxml 0.7.2 » org » jvoicexml » implementation » grammar » GrammarChecker.java
/*
 * File:    $HeadURL: https://jvoicexml.svn.sourceforge.net/svnroot/jvoicexml/core/trunk/org.jvoicexml/src/org/jvoicexml/implementation/grammar/GrammarChecker.java $
 * Version: $LastChangedRevision: 1845 $
 * Date:    $Date: 2009-10-09 09:19:57 +0200 (Fr, 09 Okt 2009) $
 * Author:  $LastChangedBy: schnelle $
 *
 * JVoiceXML - A free VoiceXML implementation.
 *
 * Copyright (C) 2008 JVoiceXML group - http://jvoicexml.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

package org.jvoicexml.implementation.grammar;

import java.util.Collection;
import java.util.Stack;

import org.mozilla.javascript.ScriptableObject;

/**
 * This class provides a means to perform evaluations on a parsed grammar.
 * @author Dirk Schnelle-Walka
 * @version $Revision: 1845 $
 * @since 0.7
 */
public final class GrammarChecker {
    /** The graph to analyze. */
    private final GrammarGraph graph;

    /** Matched tokens. */
    private final Stack<GrammarNode> matchedTokens;

    /**
     * Constructs a new object.
     * @param grammarGraph the graph to analyze.
     */
    public GrammarChecker(final GrammarGraph grammarGraph) {
        matchedTokens = new Stack<GrammarNode>();
        graph = grammarGraph;
    }
    /**
     * Checks if the given tokens can be represented using the given
     * graph.
     * @param tokens the tokens
     * @return <code>true</code> if the tokens are valid.
     */
    public boolean isValid(final String[] tokens) {
        matchedTokens.clear();
        final GrammarNode start = graph.getStartNode();
        return isValid(start, tokens)
            && (matchedTokens.size() == tokens.length);
    }

    /**
     * Retrieves the result of the grammar check process. This may differ from
     * the parsed tokens of the original utterance.
     * <p>
     * A call to this method is only valid after a call to
     * {@link #isValid(String[])} until the next validation check.
     * </p>
     * @return interpreteration result
     * TODO This is just a first attempt to go into the direction of semantic
     * interpretation and may change.
     */
    public ScriptableObject getInterpretation() {
        Collection<String> result = new java.util.ArrayList<String>();
        for (GrammarNode node : matchedTokens) {
            final GrammarNodeType type = node.getType();
            if (type == GrammarNodeType.TOKEN) {
                final TokenGrammarNode tokenNode = (TokenGrammarNode) node;
                final String token = tokenNode.getToken();
                result.add(token);
            }
        }
        return null;
    }

    /**
     * Checks if the given node is on the path.
     * @param node the node
     * @param tokens the tokens to analyze.
     * @return <code>true</code> if the node is on the path.
     */
    private boolean isValid(final GrammarNode node, final String[] tokens) {
        final GrammarNodeType type = node.getType();
        if ((type == GrammarNodeType.GRAPH) || (type == GrammarNodeType.RULE)) {
            final GrammarGraph currentGraph = (GrammarGraph) node;
            if (currentGraph.getMinRepeat() == 0) {
                final GrammarNode end = currentGraph.getEndNode();
                if (isValid(end, tokens)) {
                    return true;
                }
            }
            final GrammarNode start = currentGraph.getStartNode();
            return isValid(start, tokens);
        }

        boolean pushedNode = false;
        if (type == GrammarNodeType.TOKEN) {
            if (matchedTokens.size() >= tokens.length) {
                return false;
            }
            final TokenGrammarNode tokenNode = (TokenGrammarNode) node;
            final String token = tokenNode.getToken();
            if (token.equals(tokens[matchedTokens.size()])) {
                matchedTokens.push(node);
                pushedNode = true;
                if (matchedTokens.size() >= tokens.length) {
                    return isFinalNode(node);
                }
            } else {
                if (tokenNode.getMinRepeat() > 0) {
                    return false;
                }
            }
        }

        for (GrammarNode destination : node.getNextNodes()) {
            if (isValid(destination, tokens)) {
                return true;
            }
        }
        if (pushedNode && (matchedTokens.size() > 0)) {
            matchedTokens.pop();
        }
        return false;
    }

    /**
     * Checks if the given node is a final node. This is the case if either the
     * given node is a final node itself or if there is a way through pure
     * {@link EmptyGrammarNode}s to a final node.
     * @param node the node to inspect.
     * @return <code>true</code> if the given node is a final node.
     */
    private boolean isFinalNode(final GrammarNode node) {
        if (node.isFinalNode()) {
            return true;
        }
        for (GrammarNode destination : node.getNextNodes()) {
            final GrammarNodeType type = destination.getType();
            if (type == GrammarNodeType.GRAPH) {
                final GrammarGraph currentGraph = (GrammarGraph) destination;
                final GrammarNode start = currentGraph.getStartNode();
                if (isFinalNode(start)) {
                    return true;
                }
            } else if (type == GrammarNodeType.TOKEN) {
                return false;
            } else {
                if (isFinalNode(destination)) {
                    return true;
                }
            }
        }
        return false;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.