001 // This file is part of AceWiki.
002 // Copyright 2008-2012, AceWiki developers.
003 //
004 // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005 // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006 // the License, or (at your option) any later version.
007 //
008 // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010 // Lesser General Public License for more details.
011 //
012 // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013 // not, see http://www.gnu.org/licenses/.
014
015 package ch.uzh.ifi.attempto.acewiki.gf;
016
017 import java.util.ArrayList;
018 import java.util.HashSet;
019 import java.util.List;
020 import java.util.Set;
021
022 import org.grammaticalframework.parser.ParseState;
023
024 import ch.uzh.ifi.attempto.base.ConcreteOption;
025 import ch.uzh.ifi.attempto.base.NextTokenOptions;
026 import ch.uzh.ifi.attempto.base.PredictiveParser;
027 import ch.uzh.ifi.attempto.base.SimpleConcreteOption;
028 import ch.uzh.ifi.attempto.base.SimpleNextTokenOptions;
029
030 /**
031 * This is a predictive parser connecting to the JPGF implementation of GF.
032 *
033 * @author Tobias Kuhn
034 */
035 public class GFPredictiveParser implements PredictiveParser {
036
037 private List<String> tokens = new ArrayList<String>();
038 private ParseState parseState;
039 private NextTokenOptions nextTokenOptions;
040 private GFGrammar gfGrammar;
041 private String language;
042
043 /**
044 * Creates a new parser object for the given language.
045 *
046 * @param gfGrammar The grammar object.
047 * @param language The language.
048 */
049 public GFPredictiveParser(GFGrammar gfGrammar, String language) {
050 this.gfGrammar = gfGrammar;
051 this.language = language;
052 update();
053 }
054
055 private ParseState getParseState() {
056 if (parseState == null) {
057 parseState = gfGrammar.parse(getTokensArray(), language);
058 }
059 return parseState;
060 }
061
062 private void update() {
063 // lazy parsing
064 parseState = null;
065 nextTokenOptions = null;
066 }
067
068 public void addToken(String token) {
069 tokens.add(token);
070 update();
071 }
072
073 public void addTokens(List<String> tokens) {
074 this.tokens.addAll(tokens);
075 update();
076 }
077
078 public void removeToken() {
079 tokens.remove(tokens.size()-1);
080 update();
081 }
082
083 public void removeAllTokens() {
084 tokens.clear();
085 update();
086 }
087
088 public void setTokens(List<String> tokens) {
089 this.tokens.clear();
090 this.tokens.addAll(tokens);
091 update();
092 }
093
094 public List<String> getTokens() {
095 return tokens;
096 }
097
098 private String[] getTokensArray() {
099 return tokens.toArray(new String[] {});
100 }
101
102 public int getTokenCount() {
103 return tokens.size();
104 }
105
106 public NextTokenOptions getNextTokenOptions() {
107 if (nextTokenOptions == null) {
108 Set<ConcreteOption> options = new HashSet<ConcreteOption>();
109 for (String s : getParseState().predict()) {
110 options.add(new SimpleConcreteOption(s));
111 }
112 nextTokenOptions = new SimpleNextTokenOptions(options);
113 }
114 return nextTokenOptions;
115 }
116
117 public boolean isPossibleNextToken(String token) {
118 return getNextTokenOptions().containsToken(token);
119 }
120
121 public boolean isComplete() {
122 return getParseState().getTrees().length > 0;
123 }
124
125 public int getReference() {
126 return -1;
127 }
128
129 }