From 1846e6bf6559d0cd2f78b7bd83d8431f25f81686 Mon Sep 17 00:00:00 2001 From: hallgren Date: Mon, 9 Sep 2013 19:52:08 +0000 Subject: [PATCH] Nonlinear patterns in concrete syntax are now detected and reported as errors Before, they were silently converted to linear patterns. Nonlinear patterns in MorphoCat.gf, ParadigmsGre.gf and ParadigmsFin.gf have been make linear by renaming pattern variables. --- lib/src/catalan/MorphoCat.gf | 2 +- lib/src/finnish/ParadigmsFin.gf | 4 +- lib/src/greek/ParadigmsGre.gf | 23 +++--- src/compiler/GF/Compile/Rename.hs | 122 +++++++++++++++--------------- 4 files changed, 78 insertions(+), 73 deletions(-) diff --git a/lib/src/catalan/MorphoCat.gf b/lib/src/catalan/MorphoCat.gf index 7f65666ce..21526565e 100644 --- a/lib/src/catalan/MorphoCat.gf +++ b/lib/src/catalan/MorphoCat.gf @@ -236,7 +236,7 @@ oper mkAdj2Reg : Str -> Str -> Adj = \petit,petita -> case of { <_, _ + ("b"|"c"|"d"|"e"|"f"|"g"|"h"|"i"|"j"|"k"|"l"|"m"|"n"|"o"|"p"|"q"|"r"|"s"|"t"|"u"|"v"|"x"|"y"|"z")> => adjFidel petit ; --feminine doesn't end in "a" - => adjPrim petit ; --1) petit~petita 2) ridícul~ridícula, dolç~dolça + => adjPrim petit ; --1) petit~petita 2) ridícul~ridícula, dolç~dolça -- was nonlinear <_ + "ig", _> => adjIg petit petita ; --lleig~letja <_, _+ "na"> => adjVn petit ; --pla~plana <_, _ + ("à"|"é"|"è"|"í"|"ó"|"ò"|"ú") + _> => adjBlau petit petita ; --diari~diària diff --git a/lib/src/finnish/ParadigmsFin.gf b/lib/src/finnish/ParadigmsFin.gf index ecdcc8227..8d4888315 100644 --- a/lib/src/finnish/ParadigmsFin.gf +++ b/lib/src/finnish/ParadigmsFin.gf @@ -522,9 +522,9 @@ mkVS = overload { dSilakka ukko ukon ukkoja ; -- auto,auton <_ + "mpi", _ + ("emman" | "emmn")> => dSuurempi ukko ; <_ + "in", _ + ("imman" | "immn")> => dSuurin ukko ; - => + => -- was nonlinear dRae ukko ukon ; - => + => -- was nonlinear dRae ukko ukon ; => dRae ukko ukon ; => dArpi ukko ukon ; diff --git a/lib/src/greek/ParadigmsGre.gf b/lib/src/greek/ParadigmsGre.gf index f42cea8f3..f5df91960 100644 --- a/lib/src/greek/ParadigmsGre.gf +++ b/lib/src/greek/ParadigmsGre.gf @@ -42,14 +42,15 @@ oper mkNending : Str -> Str -> Gender -> N = \x,n,g -> case of { - => mkNoun_anthropos x n g ; - => mkNoun_kivernisi x n g ; - => mkNoun_fournaris x n g ; - => mkNoun_filakas x n g ; - => mkNoun_prosopo x n g ; - => mkNoun_fws x n g ; - => mkNoun_provlima x n g ; - => mkNoun_megethos x n g + -- all of these were nonlinear + => mkNoun_anthropos x n g ; + => mkNoun_kivernisi x n g ; + => mkNoun_fournaris x n g ; + => mkNoun_filakas x n g ; + => mkNoun_prosopo x n g ; + => mkNoun_fws x n g ; + => mkNoun_provlima x n g ; + => mkNoun_megethos x n g } ** {lock_N = <>} ; @@ -128,9 +129,9 @@ oper mkA1 : Str -> Str -> A = \x,n -> case of { - => mkAdjective4 x n ; - => mkAdjective3 x n ; - => mkAdjectiveIr x n + => mkAdjective4 x n ; -- was nonlinear + => mkAdjective3 x n ; -- was nonlinear + => mkAdjectiveIr x n -- was nonlinear } ** {lock_A = <>} ; diff --git a/src/compiler/GF/Compile/Rename.hs b/src/compiler/GF/Compile/Rename.hs index 9e959c353..6031ab938 100644 --- a/src/compiler/GF/Compile/Rename.hs +++ b/src/compiler/GF/Compile/Rename.hs @@ -39,7 +39,7 @@ import GF.Grammar.Printer import GF.Data.Operations import Control.Monad -import Data.List (nub) +import Data.List (nub,(\\)) import Text.PrettyPrint -- | this gives top-level access to renaming term input in the cc command @@ -235,76 +235,80 @@ renameTerm env vars = ren vars where -- | vars not needed in env, since patterns always overshadow old vars renamePattern :: Status -> Patt -> Check (Patt,[Ident]) -renamePattern env patt = case patt of +renamePattern env patt = + do r@(p',vs) <- renp patt + let dupl = vs \\ nub vs + unless (null dupl) $ checkError (hang (text "[C.4.13] Pattern is not linear:") 4 + (ppPatt Unqualified 0 patt)) + return r + where + renp patt = case patt of + PMacro c -> do + c' <- renid $ Vr c + case c' of + Q d -> renp $ PM d + _ -> checkError (text "unresolved pattern" <+> ppPatt Unqualified 0 patt) - PMacro c -> do - c' <- renid $ Vr c - case c' of - Q d -> renp $ PM d - _ -> checkError (text "unresolved pattern" <+> ppPatt Unqualified 0 patt) + PC c ps -> do + c' <- renid $ Cn c + case c' of + QC c -> do psvss <- mapM renp ps + let (ps,vs) = unzip psvss + return (PP c ps, concat vs) + Q _ -> checkError (text "data constructor expected but" <+> ppTerm Qualified 0 c' <+> text "is found instead") + _ -> checkError (text "unresolved data constructor" <+> ppTerm Qualified 0 c') - PC c ps -> do - c' <- renid $ Cn c - case c' of - QC c -> do psvss <- mapM renp ps - let (ps,vs) = unzip psvss - return (PP c ps, concat vs) - Q _ -> checkError (text "data constructor expected but" <+> ppTerm Qualified 0 c' <+> text "is found instead") - _ -> checkError (text "unresolved data constructor" <+> ppTerm Qualified 0 c') + PP c ps -> do + (QC c') <- renid (QC c) + psvss <- mapM renp ps + let (ps',vs) = unzip psvss + return (PP c' ps', concat vs) - PP c ps -> do - (QC c') <- renid (QC c) - psvss <- mapM renp ps - let (ps',vs) = unzip psvss - return (PP c' ps', concat vs) + PM c -> do + x <- renid (Q c) + c' <- case x of + (Q c') -> return c' + _ -> checkError (text "not a pattern macro" <+> ppPatt Qualified 0 patt) + return (PM c', []) - PM c -> do - x <- renid (Q c) - c' <- case x of - (Q c') -> return c' - _ -> checkError (text "not a pattern macro" <+> ppPatt Qualified 0 patt) - return (PM c', []) + PV x -> checks [ renid' (Vr x) >>= \t' -> case t' of + QC c -> return (PP c [],[]) + _ -> checkError (text "not a constructor") + , return (patt, [x]) + ] - PV x -> checks [ renid' (Vr x) >>= \t' -> case t' of - QC c -> return (PP c [],[]) - _ -> checkError (text "not a constructor") - , return (patt, [x]) - ] + PR r -> do + let (ls,ps) = unzip r + psvss <- mapM renp ps + let (ps',vs') = unzip psvss + return (PR (zip ls ps'), concat vs') - PR r -> do - let (ls,ps) = unzip r - psvss <- mapM renp ps - let (ps',vs') = unzip psvss - return (PR (zip ls ps'), concat vs') + PAlt p q -> do + (p',vs) <- renp p + (q',ws) <- renp q + return (PAlt p' q', vs ++ ws) - PAlt p q -> do - (p',vs) <- renp p - (q',ws) <- renp q - return (PAlt p' q', vs ++ ws) + PSeq p q -> do + (p',vs) <- renp p + (q',ws) <- renp q + return (PSeq p' q', vs ++ ws) - PSeq p q -> do - (p',vs) <- renp p - (q',ws) <- renp q - return (PSeq p' q', vs ++ ws) + PRep p -> do + (p',vs) <- renp p + return (PRep p', vs) - PRep p -> do - (p',vs) <- renp p - return (PRep p', vs) + PNeg p -> do + (p',vs) <- renp p + return (PNeg p', vs) - PNeg p -> do - (p',vs) <- renp p - return (PNeg p', vs) + PAs x p -> do + (p',vs) <- renp p + return (PAs x p', x:vs) - PAs x p -> do - (p',vs) <- renp p - return (PAs x p', x:vs) + _ -> return (patt,[]) - _ -> return (patt,[]) - - where - renp = renamePattern env - renid = renameIdentTerm env - renid' = renameIdentTerm' env + renid = renameIdentTerm env + renid' = renameIdentTerm' env renameContext :: Status -> Context -> Check Context renameContext b = renc [] where