more advanced complete function in the PGFService

This commit is contained in:
krasimir
2010-08-24 15:58:22 +00:00
parent 4df7b04935
commit d3a6866277
6 changed files with 66 additions and 65 deletions

View File

@@ -79,7 +79,6 @@ module PGF(
TcError(..), ppTcError,
-- ** Low level parsing API
complete,
Parse.ParseState,
Parse.initState, Parse.nextState, Parse.getCompletions, Parse.recoveryStates,
Parse.ParseInput(..), Parse.simpleParseInput, Parse.mkParseInput,
@@ -208,14 +207,6 @@ functions :: PGF -> [CId]
-- | The type of a given function
functionType :: PGF -> CId -> Maybe Type
-- | Complete the last word in the given string. If the input
-- is empty or ends in whitespace, the last word is considred
-- to be the empty string. This means that the completions
-- will be all possible next words.
complete :: PGF -> Language -> Type -> String
-> [String] -- ^ Possible completions,
-- including the given input.
---------------------------------------------------
-- Implementation
@@ -274,30 +265,6 @@ functionType pgf fun =
Just (ty,_,_) -> Just ty
Nothing -> Nothing
complete pgf from typ input =
let (ws,prefix) = tokensAndPrefix input
state0 = Parse.initState pgf from typ
in case loop state0 ws of
Nothing -> []
Just state -> (if null prefix && isSuccessful state then [unwords ws ++ " "] else [])
++ [unwords (ws++[c]) ++ " " | c <- Map.keys (Parse.getCompletions state prefix)]
where
isSuccessful state =
case Parse.getParseOutput state typ of
(Parse.ParseOk ts, _) -> not (null ts)
_ -> False
tokensAndPrefix :: String -> ([String],String)
tokensAndPrefix s | not (null s) && isSpace (last s) = (ws, "")
| null ws = ([],"")
| otherwise = (init ws, last ws)
where ws = words s
loop ps [] = Just ps
loop ps (t:ts) = case Parse.nextState ps (Parse.simpleParseInput t) of
Left es -> Nothing
Right ps -> loop ps ts
-- | Converts an expression to normal form
compute :: PGF -> Expr -> Expr
compute pgf = PGF.Data.normalForm (funs (abstract pgf),const Nothing) 0 []

View File

@@ -213,12 +213,15 @@ doParse pgf input mcat mfrom = showJSON $ map toJSObject
] | (fid,err) <- errs])]
doComplete :: PGF -> String -> Maybe PGF.Type -> Maybe PGF.Language -> Maybe Int -> JSValue
doComplete pgf input mcat mfrom mlimit = showJSON $ map toJSObject $ limit
[[("from", PGF.showLanguage from),("text",text)]
| (from,compls) <- complete' pgf input mcat mfrom,
text <- compls]
doComplete pgf input mcat mfrom mlimit = showJSON $ map toJSObject
[[("from", showJSON from),
("brackets", showJSON bs),
("completions", showJSON cs),
("text", showJSON s)]
| from <- froms, let (bs,s,cs) = complete' pgf from cat mlimit input]
where
limit xs = maybe xs (\n -> take n xs) mlimit
froms = maybe (PGF.languages pgf) (:[]) mfrom
cat = fromMaybe (PGF.startCat pgf) mcat
doLinearize :: PGF -> PGF.Tree -> Maybe PGF.Language -> JSValue
doLinearize pgf tree mto = showJSON $ map toJSObject
@@ -388,12 +391,29 @@ parse' pgf input mcat mfrom =
where froms = maybe (PGF.languages pgf) (:[]) mfrom
cat = fromMaybe (PGF.startCat pgf) mcat
complete' :: PGF -> String -> Maybe PGF.Type -> Maybe PGF.Language -> [(PGF.Language,[String])]
complete' pgf input mcat mfrom =
[(from,order ss) | from <- froms, let ss = PGF.complete pgf from cat input, not (null ss)]
where froms = maybe (PGF.languages pgf) (:[]) mfrom
cat = fromMaybe (PGF.startCat pgf) mcat
order = sortBy (compare `on` map toLower)
complete' :: PGF -> PGF.Language -> PGF.Type -> Maybe Int -> String
-> (PGF.BracketedString, String, [String])
complete' pgf from typ mlimit input =
let (ws,prefix) = tokensAndPrefix input
ps0 = PGF.initState pgf from typ
(ps,ws') = loop ps0 ws
bs = snd (PGF.getParseOutput ps typ)
in if not (null ws')
then (bs, unwords (if null prefix then ws' else ws'++[prefix]), [])
else (bs, prefix, maybe id take mlimit $ order $ Map.keys (PGF.getCompletions ps prefix))
where
order = sortBy (compare `on` map toLower)
tokensAndPrefix :: String -> ([String],String)
tokensAndPrefix s | not (null s) && isSpace (last s) = (ws, "")
| null ws = ([],"")
| otherwise = (init ws, last ws)
where ws = words s
loop ps [] = (ps,[])
loop ps (w:ws) = case PGF.nextState ps (PGF.simpleParseInput w) of
Left es -> (ps,w:ws)
Right ps -> loop ps ws
linearize' :: PGF -> Maybe PGF.Language -> PGF.Tree -> [(PGF.Language,String)]
linearize' pgf mto tree =

View File

@@ -2,9 +2,6 @@
APPDIR=`dirname $0`;
GWT_DIR="/home/angelov/gwt-2.0.4"
GWT_CLASSPATH="$GWT_DIR/gwt-user.jar:$GWT_DIR/gwt-dev.jar"
if [ -z "$GWT_CLASSPATH" ]; then
echo 'ERROR: $GWT_CLASSPATH is not set'
echo 'Set $GWT_CLASSPATH to point to the GWT JAR files. For example:'

View File

@@ -122,7 +122,15 @@ public class CompletionOracle extends SuggestOracle {
jsonRequest = null;
List<CompletionSuggestion> suggestions = new ArrayList<CompletionSuggestion>();
for (PGF.Completion completion : completions.iterable()) {
suggestions.add(new CompletionSuggestion(completion.getText()));
String text = completion.getBracketedString().render();
for (String tokn : completion.getCompletions()) {
StringBuilder sbuilder = new StringBuilder();
sbuilder.append(text);
if (sbuilder.length() > 0)
sbuilder.append(' ');
sbuilder.append(tokn);
suggestions.add(new CompletionSuggestion(sbuilder.toString()));
}
}
suggestionsReady(request, callback, suggestions);
}

View File

@@ -54,23 +54,16 @@ public class FridgeBagPanel extends Composite {
limit, new PGF.CompleteCallback() {
public void onResult(PGF.Completions completions) {
for (PGF.Completion completion : completions.iterable()) {
String newText = completion.getText();
if (!newText.equals(text + " ")) {
String[] words = newText.split("\\s+");
if (words.length > 0) {
String word = words[words.length - 1];
if (word.length() > 0) {
if (updatePrefixes) {
addPrefix(text, word.substring(0,1));
}
if (mainPanel.getWidgetCount() < maxMagnets) {
Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom());
mainPanel.add(magnet);
removeStyleDependentName("empty");
} else {
prefixPanel.setVisible(true);
}
}
for (String word : completion.getCompletions()) {
if (updatePrefixes) {
addPrefix(text, word.substring(0,1));
}
if (mainPanel.getWidgetCount() < maxMagnets) {
Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom());
mainPanel.add(magnet);
removeStyleDependentName("empty");
} else {
prefixPanel.setVisible(true);
}
}
}

View File

@@ -113,6 +113,8 @@ public class PGF {
protected Completion() { }
public final native String getFrom() /*-{ return this.from; }-*/;
public final native BracketedString getBracketedString() /*-{ return this.brackets; }-*/;
public final native String[] getCompletions() /*-{ return this.completions; }-*/;
public final native String getText() /*-{ return this.text; }-*/;
}
@@ -150,6 +152,20 @@ public class PGF {
public final native int getFId() /*-{ return this.fid; }-*/;
public final native int getIndex() /*-{ return this.index; }-*/;
public final native BracketedString[] getChildren() /*-{ return this.children; }-*/;
public final String render() {
if (getToken() != null)
return getToken();
else {
StringBuilder sbuilder = new StringBuilder();
for (BracketedString bs : getChildren()) {
if (sbuilder.length() > 0)
sbuilder.append(' ');
sbuilder.append(bs.render());
}
return sbuilder.toString();
}
}
}
public static class TcError extends JavaScriptObject {