forked from GitHub/gf-core
more advanced complete function in the PGFService
This commit is contained in:
@@ -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 []
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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:'
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user