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 }