From 2d5f98dc05dad72b23f2d42c46800d3a77e37fa7 Mon Sep 17 00:00:00 2001 From: aarne Date: Mon, 17 Dec 2007 18:12:46 +0000 Subject: [PATCH] took back smart type of Int ; Digits type in resource and some adjustments of Det syntax (not yet for romance and russian) --- lib/resource/abstract/Cat.gf | 11 +- lib/resource/abstract/Noun.gf | 20 ++- lib/resource/abstract/Numeral.gf | 11 ++ lib/resource/abstract/Structural.gf | 4 +- lib/resource/common/ParamX.gf | 7 + lib/resource/danish/NumeralDan.gf | 44 ++++-- lib/resource/danish/StructuralDan.gf | 4 +- lib/resource/english/CatEng.gf | 3 +- lib/resource/english/NounEng.gf | 30 ++-- lib/resource/english/NumeralEng.gf | 51 +++++++ lib/resource/english/StructuralEng.gf | 4 +- lib/resource/finnish/CatFin.gf | 5 +- lib/resource/finnish/NounFin.gf | 30 ++-- lib/resource/finnish/NumeralFin.gf | 37 +++++ lib/resource/finnish/StructuralFin.gf | 6 +- lib/resource/german/CatGer.gf | 5 +- lib/resource/german/NounGer.gf | 12 +- lib/resource/german/NumeralGer.gf | 38 +++++ lib/resource/german/StructuralGer.gf | 8 +- lib/resource/norwegian/NumeralNor.gf | 38 +++++ lib/resource/norwegian/StructuralNor.gf | 4 +- lib/resource/scandinavian/CatScand.gf | 7 +- lib/resource/scandinavian/NounScand.gf | 25 ++-- lib/resource/swedish/NumeralSwe.gf | 36 +++++ lib/resource/swedish/StructuralSwe.gf | 4 +- src/GF/Devel/GrammarToGFCC.hs | 4 +- src/GF/GFCC/Linearize.hs | 5 +- src/GF/GFCC/Raw/ConvertGFCC.hs | 4 +- src/GF/GFCC/doc/gfcc.txt | 9 +- src/GF/GFCC/doc/syntax.txt | 182 ++++++++++++++++++++++++ src/GF/Grammar/Lookup.hs | 8 +- 31 files changed, 560 insertions(+), 96 deletions(-) create mode 100644 src/GF/GFCC/doc/syntax.txt diff --git a/lib/resource/abstract/Cat.gf b/lib/resource/abstract/Cat.gf index aa3133979..cfc13e52e 100644 --- a/lib/resource/abstract/Cat.gf +++ b/lib/resource/abstract/Cat.gf @@ -78,9 +78,7 @@ abstract Cat = Common ** { Pron ; -- personal pronoun e.g. "she" Det ; -- determiner phrase e.g. "those seven" Predet ; -- predeterminer (prefixed Quant) e.g. "all" - QuantSg ;-- quantifier ('nucleus' of sing. Det) e.g. "every" - QuantPl ;-- quantifier ('nucleus' of plur. Det) e.g. "many" - Quant ; -- quantifier with both sg and pl e.g. "this/these" + Quant ; -- quantifier ('nucleus' of Det) e.g. "this/these" Num ; -- cardinal number (used with QuantPl) e.g. "seven" Ord ; -- ordinal number (used in Det) e.g. "seventh" @@ -88,7 +86,8 @@ abstract Cat = Common ** { -- Constructed in [Numeral Numeral.html]. - Numeral;-- cardinal or ordinal, e.g. "five/fifth" + Numeral ; -- cardinal or ordinal, e.g. "five/fifth" + Digits ; -- cardinal or ordinal, e.g. "1,000/1,000th" --2 Structural words @@ -121,4 +120,8 @@ abstract Cat = Common ** { N3 ; -- three-place relational noun e.g. "connection" PN ; -- proper name e.g. "Paris" +-- DEPRECATED: QuantSg, QuantPl +--- QuantSg ;-- quantifier ('nucleus' of sing. Det) e.g. "every" +--- QuantPl ;-- quantifier ('nucleus' of plur. Det) e.g. "many" + } diff --git a/lib/resource/abstract/Noun.gf b/lib/resource/abstract/Noun.gf index 8e2d1a5a9..a97799647 100644 --- a/lib/resource/abstract/Noun.gf +++ b/lib/resource/abstract/Noun.gf @@ -35,13 +35,17 @@ abstract Noun = Cat ** { -- (This is modified from CLE by further dividing their $Num$ into -- cardinal and ordinal.) - DetSg : QuantSg -> Ord -> Det ; -- this best man - DetPl : QuantPl -> Num -> Ord -> Det ; -- these five best men + DetSg : Quant -> Ord -> Det ; -- this best man + DetPl : Quant -> Num -> Ord -> Det ; -- these five best men + +-- Notice that $DetPl$ can still result in a singular determiner, because +-- "one" is a numeral: "this one man". -- Quantifiers that have both forms can be used in both ways. - SgQuant : Quant -> QuantSg ; -- this - PlQuant : Quant -> QuantPl ; -- these +--- DEPRECATED: no longer needed +--- SgQuant : Quant -> QuantSg ; -- this +--- PlQuant : Quant -> QuantPl ; -- these -- Pronouns have possessive forms. Genitives of other kinds -- of noun phrases are not given here, since they are not possible @@ -58,7 +62,8 @@ abstract Noun = Cat ** { -- $Num$ consists of either digits or numeral words. - NumInt : Int -> Num ; -- 51 + NumInt : Int -> Num ; -- 51 (DEPRECATED) + NumDigits : Digits -> Num ; -- 51 NumNumeral : Numeral -> Num ; -- fifty-one -- The construction of numerals is defined in [Numeral Numeral.html]. @@ -69,7 +74,8 @@ abstract Noun = Cat ** { -- $Ord$ consists of either digits or numeral words. - OrdInt : Int -> Ord ; -- 51st + OrdInt : Int -> Ord ; -- 51st (DEPRECATED) + OrdDigits : Digits -> Ord ; -- 51st OrdNumeral : Numeral -> Ord ; -- fifty-first -- Superlative forms of adjectives behave syntactically in the same way as @@ -88,7 +94,7 @@ abstract Noun = Cat ** { -- not distinguish mass nouns from other common nouns, which can result -- in semantically odd expressions. - MassDet : QuantSg ; -- (beer) + MassDet : Quant ; -- (beer) -- Other determiners are defined in [Structural Structural.html]. diff --git a/lib/resource/abstract/Numeral.gf b/lib/resource/abstract/Numeral.gf index e9c8d0f9b..68fcb90d0 100644 --- a/lib/resource/abstract/Numeral.gf +++ b/lib/resource/abstract/Numeral.gf @@ -46,4 +46,15 @@ fun pot3 : Sub1000 -> Sub1000000 ; -- m * 1000 pot3plus : Sub1000 -> Sub1000 -> Sub1000000 ; -- m * 1000 + n +-- Numerals as sequences of digits have a separate, simpler grammar + + cat + Dig ; + + fun + IDig : Dig -> Digits ; + IIDig : Dig -> Digits -> Digits ; + + D_0, D_1, D_2, D_3, D_4, D_5, D_6, D_7, D_8, D_9 : Dig ; + } diff --git a/lib/resource/abstract/Structural.gf b/lib/resource/abstract/Structural.gf index 402e9ed4a..511416346 100644 --- a/lib/resource/abstract/Structural.gf +++ b/lib/resource/abstract/Structural.gf @@ -36,7 +36,7 @@ abstract Structural = Cat ** { everybody_NP : NP ; everything_NP : NP ; everywhere_Adv : Adv ; - first_Ord : Ord ; +--- first_Ord : Ord ; DEPRECATED few_Det : Det ; for_Prep : Prep ; from_Prep : Prep ; @@ -59,7 +59,7 @@ abstract Structural = Cat ** { must_VV : VV ; no_Phr : Phr ; on_Prep : Prep ; - one_Quant : QuantSg ; +--- one_Quant : QuantSg ; DEPRECATED only_Predet : Predet ; or_Conj : Conj ; otherwise_PConj : PConj ; diff --git a/lib/resource/common/ParamX.gf b/lib/resource/common/ParamX.gf index 9710eb669..5e55d4958 100644 --- a/lib/resource/common/ParamX.gf +++ b/lib/resource/common/ParamX.gf @@ -53,4 +53,11 @@ resource ParamX = open Prelude in { } } ; +-- To count the length of a tail in a sequence of digits, e.g. to put commas +-- as in 1,000,000. + + param + DTail = T1 | T2 | T3 ; + + } diff --git a/lib/resource/danish/NumeralDan.gf b/lib/resource/danish/NumeralDan.gf index 302f96542..93433d8e5 100644 --- a/lib/resource/danish/NumeralDan.gf +++ b/lib/resource/danish/NumeralDan.gf @@ -44,12 +44,40 @@ lin n9 = mkTal "ni" "nitten" "halvfems" "niende" "halvfemsindstyvende" ; pot3 n = numPl (\\g => n.s ! invNum ++ cardOrd "tusind" "tusinde" ! g) ; pot3plus n m = {s = \\g => n.s ! invNum ++ "tusind" ++ "og" ++ m.s ! g ; n =Pl} ; -} + lincat + Dig = TDigit ; -{- -lincat - Digit = {s : DForm => CardOrd => Str} ; - Sub10 = {s : DForm => CardOrd => Str ; n : Number} ; - Sub100, Sub1000, Sub1000000 = - {s : CardOrd => Str ; n : Number} ; --} + lin + IDig d = d ; + + IIDig d i = { + s = \\o => d.s ! o ++ i.s ! o ; + n = Pl + } ; + + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1e" Sg ; + D_2 = mk2Dig "2" "2e" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + "e") ; + + mk3Dig : Str -> Str -> Number -> TDigit = \c,o,n -> { + s = table {NCard _ => c ; NOrd _ => o} ; + n = n + } ; + + TDigit = { + n : Number ; + s : CardOrd => Str + } ; + +} diff --git a/lib/resource/danish/StructuralDan.gf b/lib/resource/danish/StructuralDan.gf index 6a848462e..b38396827 100644 --- a/lib/resource/danish/StructuralDan.gf +++ b/lib/resource/danish/StructuralDan.gf @@ -29,7 +29,7 @@ concrete StructuralDan of Structural = CatDan ** everything_NP = regNP "alt" "alts" SgNeutr ; everywhere_Adv = ss "overalt" ; few_Det = {s = \\_,_ => "få" ; n = Pl ; det = DDef Indef} ; - first_Ord = {s = "første" ; isDet = True} ; +--- first_Ord = {s = "første" ; isDet = True} ; for_Prep = ss "for" ; from_Prep = ss "fra" ; he_Pron = MorphoDan.mkNP "han" "ham" "hans" "hans" "hans" SgUtr P3 ; @@ -53,7 +53,7 @@ concrete StructuralDan of Structural = CatDan ** mkV "måtte" "må" "må" "måtte" "måttet" "mått" ** {c2 = [] ; lock_VV = <>} ; no_Phr = ss ["Nej"] ; on_Prep = ss "på" ; - one_Quant = {s = \\_ => genderForms ["en"] ["et"] ; n = Sg ; det = DIndef} ; --- ei +--- one_Quant = {s = \\_ => genderForms ["en"] ["et"] ; n = Sg ; det = DIndef} ; --- ei only_Predet = {s = \\_ => "kun"} ; or_Conj = ss "eller" ** {n = Sg} ; otherwise_PConj = ss "anderledes" ; diff --git a/lib/resource/english/CatEng.gf b/lib/resource/english/CatEng.gf index 543b9ac39..685fad9ea 100644 --- a/lib/resource/english/CatEng.gf +++ b/lib/resource/english/CatEng.gf @@ -53,13 +53,14 @@ concrete CatEng of Cat = CommonX ** open ResEng, Prelude in { CN = {s : Number => Case => Str} ; NP, Pron = {s : Case => Str ; a : Agr} ; Det = {s : Str ; n : Number} ; - Predet, QuantSg, QuantPl, Ord = {s : Str} ; + Predet, Ord = {s : Str} ; Num = {s : Str; n : Number } ; Quant = {s : Number => Str} ; -- Numeral Numeral = {s : CardOrd => Str ; n : Number} ; + Digits = {s : CardOrd => Str ; n : Number ; tail : DTail} ; -- Structural diff --git a/lib/resource/english/NounEng.gf b/lib/resource/english/NounEng.gf index 003839fb7..c282c16b0 100644 --- a/lib/resource/english/NounEng.gf +++ b/lib/resource/english/NounEng.gf @@ -26,33 +26,37 @@ concrete NounEng of Noun = CatEng ** open ResEng, Prelude in { } ; DetSg quant ord = { - s = quant.s ++ ord.s ; + s = quant.s ! Sg ++ ord.s ; n = Sg } ; DetPl quant num ord = { - s = quant.s ++ num.s ++ ord.s ; + s = quant.s ! num.n ++ num.s ++ ord.s ; n = num.n } ; - SgQuant quant = {s = quant.s ! Sg} ; - PlQuant quant = {s = quant.s ! Pl} ; +--- SgQuant quant = {s = quant.s ! Sg} ; DEPRECATED +--- PlQuant quant = {s = quant.s ! Pl} ; PossPron p = {s = \\_ => p.s ! Gen} ; NoNum = {s = []; n = Pl } ; NoOrd = {s = []} ; - NumInt n = {s = n.s; n = table (Predef.Ints 1 * Predef.Ints 9) { - <0,1> => Sg ; - _ => Pl - } ! ---- <1,2> ---- parser bug (AR 2/6/2007) - - } ; + NumDigits n = {s = n.s ! NCard ; n = n.n} ; - OrdInt n = {s = n.s ++ "th"} ; --- + NumInt n = {s = n.s ; n = Pl} ; + --table (Predef.Ints 1 * Predef.Ints 9) { + -- <0,1> => Sg ; + -- _ => Pl -- DEPRECATED + -- } ! <1,2> ---- parser bug (AR 2/6/2007) + -- ---- + -- } ; - NumNumeral numeral = {s = numeral.s ! NCard; n = numeral.n } ; + OrdInt n = {s = n.s ++ "th"} ; --- DEPRECATED + OrdDigits n = {s = n.s ! NOrd} ; + + NumNumeral numeral = {s = numeral.s ! NCard; n = numeral.n} ; OrdNumeral numeral = {s = numeral.s ! NOrd} ; AdNum adn num = {s = adn.s ++ num.s; n = num.n } ; @@ -68,7 +72,7 @@ concrete NounEng of Noun = CatEng ** open ResEng, Prelude in { } } ; - MassDet = {s = [] ; n = Sg} ; + MassDet = {s = \\_ => []} ; UseN n = n ; UseN2 n = n ; diff --git a/lib/resource/english/NumeralEng.gf b/lib/resource/english/NumeralEng.gf index ecb3e5cca..0af833c56 100644 --- a/lib/resource/english/NumeralEng.gf +++ b/lib/resource/english/NumeralEng.gf @@ -41,4 +41,55 @@ lin pot3 n = { s = \\c => n.s ! NCard ++ mkCard c "thousand" ; n = Pl} ; lin pot3plus n m = { s = \\c => n.s ! NCard ++ "thousand" ++ m.s ! c ; n = Pl} ; + +-- numerals as sequences of digits + + lincat + Dig = TDigit ; + + lin + IDig d = d ** {tail = T1} ; + + IIDig d i = { + s = \\o => d.s ! o ++ commaIf i.tail ++ i.s ! o ; + n = Pl ; + tail = inc i.tail + } ; + + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1st" Sg ; + D_2 = mk2Dig "2" "2nd" ; + D_3 = mk2Dig "3" "3rd" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + commaIf : DTail -> Str = \t -> case t of { + T3 => "," ; + _ => [] + } ; + + inc : DTail -> DTail = \t -> case t of { + T1 => T2 ; + T2 => T3 ; + T3 => T1 + } ; + + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + "th") ; + + mk3Dig : Str -> Str -> Number -> TDigit = \c,o,n -> { + s = table {NCard => c ; NOrd => o} ; + n = n + } ; + + TDigit = { + n : Number ; + s : CardOrd => Str + } ; + } diff --git a/lib/resource/english/StructuralEng.gf b/lib/resource/english/StructuralEng.gf index c6253f6b4..0b19685c5 100644 --- a/lib/resource/english/StructuralEng.gf +++ b/lib/resource/english/StructuralEng.gf @@ -38,7 +38,7 @@ concrete StructuralEng of Structural = CatEng ** everything_NP = regNP "everything" Sg ; everywhere_Adv = ss "everywhere" ; few_Det = mkDeterminer Pl "few" ; - first_Ord = ss "first" ; +--- first_Ord = ss "first" ; DEPRECATED for_Prep = ss "for" ; from_Prep = ss "from" ; he_Pron = mkNP "he" "him" "his" Sg P3 ; @@ -71,7 +71,7 @@ concrete StructuralEng of Structural = CatEng ** } ; no_Phr = ss "no" ; on_Prep = ss "on" ; - one_Quant = mkDeterminer Sg "one" ; +---- one_Quant = mkDeterminer Sg "one" ; -- DEPRECATED only_Predet = ss "only" ; or_Conj = ss "or" ** {n = Sg} ; otherwise_PConj = ss "otherwise" ; diff --git a/lib/resource/finnish/CatFin.gf b/lib/resource/finnish/CatFin.gf index 42f62dd42..6797ae59b 100644 --- a/lib/resource/finnish/CatFin.gf +++ b/lib/resource/finnish/CatFin.gf @@ -56,15 +56,16 @@ concrete CatFin of Cat = CommonX ** open ResFin, Prelude in { isPoss : Bool ; -- True (a possessive suffix is present) isDef : Bool -- True (verb agrees in Pl, Nom is not Part) } ; - QuantSg, QuantPl = {s1 : Case => Str ; s2 : Str ; isPoss, isDef : Bool} ; +---- QuantSg, QuantPl = {s1 : Case => Str ; s2 : Str ; isPoss, isDef : Bool} ; Ord = {s : Number => Case => Str} ; Predet = {s : Number => NPForm => Str} ; Quant = {s1 : Number => Case => Str ; s2 : Str ; isPoss, isDef : Bool} ; - Num = {s : Number => Case => Str ; isNum : Bool} ; + Num = {s : Number => Case => Str ; isNum : Bool ; n : Number} ; -- Numeral Numeral = {s : CardOrd => Str ; n : Number} ; + Digits = {s : CardOrd => Str ; n : Number} ; -- Structural diff --git a/lib/resource/finnish/NounFin.gf b/lib/resource/finnish/NounFin.gf index 544d53748..b7c97793e 100644 --- a/lib/resource/finnish/NounFin.gf +++ b/lib/resource/finnish/NounFin.gf @@ -61,7 +61,7 @@ concrete NounFin of Noun = CatFin ** open ResFin, Prelude in { } ; DetSg quant ord = { - s1 = \\c => quant.s1 ! c ++ ord.s ! Sg ! c ; + s1 = \\c => quant.s1 ! Sg ! c ++ ord.s ! Sg ! c ; s2 = quant.s2 ; n = Sg ; isNum = False ; @@ -70,14 +70,15 @@ concrete NounFin of Noun = CatFin ** open ResFin, Prelude in { } ; DetPl quant num ord = { - s1 = \\c => quant.s1 ! c ++ num.s ! Sg ! c ++ ord.s ! Pl ! c ; + s1 = \\c => quant.s1 ! num.n ! c ++ num.s ! Sg ! c ++ ord.s ! Pl ! c ; s2 = quant.s2 ; - n = Pl ; + n = num.n ; isNum = num.isNum ; isPoss = quant.isPoss ; isDef = quant.isDef } ; +{- --- DEPREC SgQuant quant = { s1 = quant.s1 ! Sg ; s2 = quant.s2 ; @@ -92,7 +93,7 @@ concrete NounFin of Noun = CatFin ** open ResFin, Prelude in { isPoss = quant.isPoss ; isDef = quant.isDef } ; - +-} PossPron p = { s1 = \\_,_ => p.s ! NPCase Gen ; s2 = BIND ++ possSuffix p.a ; @@ -101,16 +102,27 @@ concrete NounFin of Noun = CatFin ** open ResFin, Prelude in { isDef = True --- "minun kolme autoani ovat" ; thus "...on" is missing } ; - NoNum = {s = \\_,_ => [] ; isNum = False} ; + NoNum = {s = \\_,_ => [] ; isNum = False ; n = Pl} ; NoOrd = {s = \\_,_ => []} ; - NumInt n = {s = \\_,_ => n.s ; isNum = True} ; + NumInt n = {s = \\_,_ => n.s ; isNum = True ; n = Pl} ; --DEPREC OrdInt n = {s = \\_,_ => n.s ++ "."} ; - NumNumeral numeral = {s = \\n,c => numeral.s ! NCard (NCase n c) ; isNum = True} ; + NumDigits numeral = { + s = \\n,c => numeral.s ! NCard (NCase n c) ; + n = numeral.n ; + isNum = True + } ; + OrdDigits numeral = {s = \\n,c => numeral.s ! NOrd (NCase n c)} ; + + NumNumeral numeral = { + s = \\n,c => numeral.s ! NCard (NCase n c) ; + n = numeral.n ; + isNum = True + } ; OrdNumeral numeral = {s = \\n,c => numeral.s ! NOrd (NCase n c)} ; - AdNum adn num = {s = \\n,c => adn.s ++ num.s ! n ! c ; isNum = num.isNum} ; + AdNum adn num = {s = \\n,c => adn.s ++ num.s ! n ! c ; isNum = num.isNum ; n = num.n} ; OrdSuperl a = {s = \\n,c => a.s ! Superl ! AN (NCase n c)} ; @@ -128,7 +140,7 @@ concrete NounFin of Noun = CatFin ** open ResFin, Prelude in { } ; MassDet = { - s1 = \\_ => [] ; --- Nom is Part ? + s1 = \\_,_ => [] ; --- Nom is Part ? s2 = [] ; isNum,isPoss,isDef = False } ; diff --git a/lib/resource/finnish/NumeralFin.gf b/lib/resource/finnish/NumeralFin.gf index e868af284..417ba74d4 100644 --- a/lib/resource/finnish/NumeralFin.gf +++ b/lib/resource/finnish/NumeralFin.gf @@ -138,5 +138,42 @@ oper } } ; + + lincat + Dig = TDigit ; + + lin + IDig d = d ; + + IIDig d i = { + s = \\o => d.s ! o ++ i.s ! o ; + n = Pl + } ; + + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1." MorphoFin.Sg ; + D_2 = mkDig "2" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o MorphoFin.Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + ".") ; + + mk3Dig : Str -> Str -> MorphoFin.Number -> TDigit = \c,o,n -> { + s = table {NCard _ => c ; NOrd _ => o} ; + n = n + } ; + + TDigit = { + n : MorphoFin.Number ; + s : CardOrd => Str + } ; + } diff --git a/lib/resource/finnish/StructuralFin.gf b/lib/resource/finnish/StructuralFin.gf index 52b061784..c9ab00c51 100644 --- a/lib/resource/finnish/StructuralFin.gf +++ b/lib/resource/finnish/StructuralFin.gf @@ -38,7 +38,7 @@ concrete StructuralFin of Structural = CatFin ** {lock_N = <>}) Sg ; everywhere_Adv = ss "kaikkialla" ; few_Det = mkDet Sg (regN "harva") ; - first_Ord = {s = \\n,c => (regN "ensimmäinen").s ! NCase n c} ; +--- first_Ord = {s = \\n,c => (regN "ensimmäinen").s ! NCase n c} ; for_Prep = casePrep allative ; from_Prep = casePrep elative ; he_Pron = mkPronoun "hän" "hänen" "häntä" "hänenä" "häneen" Sg P3 ; @@ -65,9 +65,7 @@ concrete StructuralFin of Structural = CatFin ** must_VV = subjcaseV (regV "täytyä") genitive ; no_Phr = ss "ei" ; on_Prep = casePrep adessive ; - one_Quant = mkDet Sg - (nhn (mkSubst "ä" "yksi" "yhde" "yhte" "yhtä" "yhteen" "yksi" "yksi" - "yksien" "yksiä" "yksiin")) ; +--- one_Quant = mkDet Sg DEPREC only_Predet = {s = \\_,_ => "vain"} ; or_Conj = ss "tai" ** {n = Sg} ; otherwise_PConj = ss "muuten" ; diff --git a/lib/resource/german/CatGer.gf b/lib/resource/german/CatGer.gf index 3ec126824..f901ca8e4 100644 --- a/lib/resource/german/CatGer.gf +++ b/lib/resource/german/CatGer.gf @@ -47,7 +47,7 @@ concrete CatGer of Cat = NP = {s : Case => Str ; a : Agr} ; Pron = {s : NPForm => Str ; a : Agr} ; Det = {s : Gender => Case => Str ; n : Number ; a : Adjf} ; - QuantSg, QuantPl = {s : Gender => Case => Str ; a : Adjf} ; +--- QuantSg, QuantPl = {s : Gender => Case => Str ; a : Adjf} ; DEPREC Quant = {s : Number => Gender => Case => Str ; a : Adjf} ; Predet = {s : Number => Gender => Case => Str} ; Num = {s : Str; n : Number } ; @@ -55,7 +55,8 @@ concrete CatGer of Cat = -- Numeral - Numeral = {s : CardOrd => Str; n : Number } ; + Numeral = {s : CardOrd => Str ; n : Number } ; + Digits = {s : CardOrd => Str ; n : Number } ; -- Structural diff --git a/lib/resource/german/NounGer.gf b/lib/resource/german/NounGer.gf index 46bb68a5e..b9e5c73eb 100644 --- a/lib/resource/german/NounGer.gf +++ b/lib/resource/german/NounGer.gf @@ -36,7 +36,7 @@ concrete NounGer of Noun = CatGer ** open ResGer, Prelude in { n = Sg ; a = quant.a in { - s = \\g,c => quant.s ! g ! c ++ + s = \\g,c => quant.s ! n ! g ! c ++ ord.s ! agrAdj g (adjfCase a c) n c ; n = n ; a = a @@ -46,12 +46,13 @@ concrete NounGer of Noun = CatGer ** open ResGer, Prelude in { n = num.n ; a = quant.a in { - s = \\g,c => quant.s ! g ! c ++ + s = \\g,c => quant.s ! n ! g ! c ++ num.s ++ ord.s ! agrAdj g (adjfCase a c) n c ; n = n ; a = a } ; +{- --- DEPREC SgQuant q = { s = q.s ! Sg ; a = q.a @@ -60,6 +61,7 @@ concrete NounGer of Noun = CatGer ** open ResGer, Prelude in { s = q.s ! Pl ; a = q.a } ; +-} PossPron p = { s = \\n,g,c => p.s ! NPPoss (gennum g n) c ; @@ -76,6 +78,9 @@ concrete NounGer of Noun = CatGer ** open ResGer, Prelude in { } ; OrdInt n = {s = \\_ => n.s ++ "."} ; + NumDigits numeral = {s = numeral.s ! NCard; n = numeral.n } ; + OrdDigits numeral = {s = \\af => numeral.s ! NOrd af} ; + NumNumeral numeral = {s = numeral.s ! NCard; n = numeral.n } ; OrdNumeral numeral = {s = \\af => numeral.s ! NOrd af} ; @@ -97,8 +102,7 @@ concrete NounGer of Noun = CatGer ** open ResGer, Prelude in { } ; MassDet = { - s = \\g,c => [] ; - n = Sg ; + s = \\_,g,c => [] ; a = Strong } ; diff --git a/lib/resource/german/NumeralGer.gf b/lib/resource/german/NumeralGer.gf index 812661ed7..a6429bbcc 100644 --- a/lib/resource/german/NumeralGer.gf +++ b/lib/resource/german/NumeralGer.gf @@ -45,4 +45,42 @@ lin pot3plus n m = {s = \\g => n.s ! invNum ++ "tausend" ++ m.s ! g ; n = Pl} ; + + lincat + Dig = TDigit ; + + lin + IDig d = d ; + + IIDig d i = { + s = \\o => d.s ! o ++ i.s ! o ; + n = Pl + } ; + + ---- TODO: case endings of ordinals + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1e" Sg ; + D_2 = mk2Dig "2" "2e" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + "e") ; + + mk3Dig : Str -> Str -> Number -> TDigit = \c,o,n -> { + s = table {NCard => c ; NOrd _ => o} ; + n = n + } ; + + TDigit = { + n : Number ; + s : CardOrd => Str + } ; + } \ No newline at end of file diff --git a/lib/resource/german/StructuralGer.gf b/lib/resource/german/StructuralGer.gf index 8e18db824..3cd2a839d 100644 --- a/lib/resource/german/StructuralGer.gf +++ b/lib/resource/german/StructuralGer.gf @@ -34,7 +34,7 @@ concrete StructuralGer of Structural = CatGer ** everything_NP = nameNounPhrase {s = caselist "alles" "alles" "allem" "alles"} ; everywhere_Adv = ss "überall" ; few_Det = detLikeAdj Pl "wenig" ; - first_Ord = {s = (regA "erst").s ! Posit} ; +---- first_Ord = {s = (regA "erst").s ! Posit} ; for_Prep = mkPrep "für" Acc ; from_Prep = mkPrep "aus" Dat ; he_Pron = mkPronPers "er" "ihn" "ihm" "seiner" "sein" Masc Sg P3 ; @@ -59,11 +59,7 @@ concrete StructuralGer of Structural = CatGer ** "mußte" "mußtest" "mußten" "mußtet" "müßte" "gemußt" [] VHaben) ; - one_Quant = { - s = \\g,c => "ein" + pronEnding ! GSg g ! c ; - n = Sg ; - a = Strong - } ; +--- one_Quant = DEPREC only_Predet = {s = \\_,_,_ => "nur"} ; no_Phr = ss "nein" ; on_Prep = mkPrep "auf" Dat ; diff --git a/lib/resource/norwegian/NumeralNor.gf b/lib/resource/norwegian/NumeralNor.gf index 8407b0d53..adf240c82 100644 --- a/lib/resource/norwegian/NumeralNor.gf +++ b/lib/resource/norwegian/NumeralNor.gf @@ -43,5 +43,43 @@ lin pot3plus n m = {s = \\g => n.s ! invNum ++ "tusen" ++ "og" ++ m.s ! g ; n = Pl} ; +-- Numerals from sequences of digits. + + lincat + Dig = TDigit ; + + lin + IDig d = d ; + + IIDig d i = { + s = \\o => d.s ! o ++ i.s ! o ; + n = Pl + } ; + + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1e" Sg ; + D_2 = mk2Dig "2" "2e" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + "e") ; + + mk3Dig : Str -> Str -> Number -> TDigit = \c,o,n -> { + s = table {NCard _ => c ; NOrd _ => o} ; + n = n + } ; + + TDigit = { + n : Number ; + s : CardOrd => Str + } ; + } diff --git a/lib/resource/norwegian/StructuralNor.gf b/lib/resource/norwegian/StructuralNor.gf index 4792bdda9..267cf8949 100644 --- a/lib/resource/norwegian/StructuralNor.gf +++ b/lib/resource/norwegian/StructuralNor.gf @@ -29,7 +29,7 @@ concrete StructuralNor of Structural = CatNor ** everything_NP = regNP "alt" "alts" SgNeutr ; everywhere_Adv = ss "overalt" ; few_Det = {s = \\_,_ => "få" ; n = Pl ; det = DDef Indef} ; - first_Ord = {s = "første" ; isDet = True} ; +--- first_Ord = {s = "første" ; isDet = True} ; DEPREC for_Prep = ss "for" ; from_Prep = ss "fra" ; he_Pron = MorphoNor.mkNP "han" "ham" "hans" "hans" "hans" SgUtr P3 ; @@ -53,7 +53,7 @@ concrete StructuralNor of Structural = CatNor ** mkV "måtte" "må" "må" "måtte" "måttet" "mått" ** {c2 = [] ; lock_VV = <>} ; no_Phr = ss ["Nei"] ; on_Prep = ss "på" ; - one_Quant = {s = \\_ => genderForms ["en"] ["et"] ; n = Sg ; det = DIndef} ; --- ei +--- one_Quant = {s = \\_ => genderForms ["en"] ["et"] ; n = Sg ; det = DIndef} ; DEPREC only_Predet = {s = \\_ => "kun"} ; or_Conj = ss "eller" ** {n = Sg} ; otherwise_PConj = ss "annarledes" ; diff --git a/lib/resource/scandinavian/CatScand.gf b/lib/resource/scandinavian/CatScand.gf index 2274445e6..9c0fdaf43 100644 --- a/lib/resource/scandinavian/CatScand.gf +++ b/lib/resource/scandinavian/CatScand.gf @@ -60,16 +60,17 @@ incomplete concrete CatScand of Cat = CN = {s : Number => DetSpecies => Case => Str ; g : Gender ; isMod : Bool} ; NP,Pron = {s : NPForm => Str ; a : Agr} ; Det = {s : Bool => Gender => Str ; n : Number ; det : DetSpecies} ; - QuantSg = {s : Bool => Gender => Str ; det : DetSpecies} ; - QuantPl = {s : Bool => Gender => Str ; det : DetSpecies} ; +--- QuantSg = {s : Bool => Gender => Str ; det : DetSpecies} ; +--- QuantPl = {s : Bool => Gender => Str ; n : Number ; det : DetSpecies} ; Quant = {s : Number => Bool => Gender => Str ; det : DetSpecies} ; Predet = {s : GenNum => Str} ; - Num = {s : Gender => Str ; isDet : Bool} ; + Num = {s : Gender => Str ; isDet : Bool ; n : Number} ; Ord = {s : Str ; isDet : Bool} ; -- Numeral Numeral = {s : CardOrd => Str ; n : Number} ; + Digits = {s : CardOrd => Str ; n : Number} ; -- Structural diff --git a/lib/resource/scandinavian/NounScand.gf b/lib/resource/scandinavian/NounScand.gf index 2f20add65..bb89d659e 100644 --- a/lib/resource/scandinavian/NounScand.gf +++ b/lib/resource/scandinavian/NounScand.gf @@ -46,17 +46,18 @@ incomplete concrete NounScand of Noun = } ; DetSg quant ord = { - s = \\b,g => quant.s ! (orB b ord.isDet) ! g ++ ord.s ; + s = \\b,g => quant.s ! Sg ! (orB b ord.isDet) ! g ++ ord.s ; n = Sg ; det = quant.det } ; DetPl quant num ord = { - s = \\b,g => quant.s ! (orB b (orB num.isDet ord.isDet)) ! g ++ + s = \\b,g => quant.s ! num.n ! (orB b (orB num.isDet ord.isDet)) ! g ++ num.s ! g ++ ord.s ; - n = Pl ; + n = num.n ; det = quant.det } ; +{- --- DEPREC SgQuant quant = { s = quant.s ! Sg ; n = Sg ; @@ -67,22 +68,26 @@ incomplete concrete NounScand of Noun = n = Pl ; det = quant.det } ; +-} PossPron p = { s = \\n,_,g => p.s ! NPPoss (gennum g n) ; det = DDef Indef } ; - NoNum = {s = \\_ => [] ; isDet = False} ; + NoNum = {s = \\_ => [] ; isDet = False ; n = Pl} ; NoOrd = {s = [] ; isDet = False} ; - NumInt n = {s = \\_ => n.s ; isDet = True} ; - OrdInt n = {s = n.s ++ ":e" ; isDet = True} ; --- + NumInt n = {s = \\_ => n.s ; isDet = True ; n = Pl} ; --- DEPRECATED + OrdInt n = {s = n.s ++ ":e" ; isDet = True} ; --- DEPRECATED - NumNumeral numeral = {s = \\g => numeral.s ! NCard g ; isDet = True} ; - OrdNumeral numeral = {s = numeral.s ! NOrd SupWeak ; isDet = True} ; + NumDigits nu = {s = \\g => nu.s ! NCard g ; isDet = True ; n = nu.n} ; + OrdDigits nu = {s = nu.s ! NOrd SupWeak ; isDet = True} ; - AdNum adn num = {s = \\g => adn.s ++ num.s ! g ; isDet = True} ; + NumNumeral nu = {s = \\g => nu.s ! NCard g ; isDet = True ; n = nu.n} ; + OrdNumeral nu = {s = nu.s ! NOrd SupWeak ; isDet = True} ; + + AdNum adn num = {s = \\g => adn.s ++ num.s ! g ; isDet = True ; n = num.n} ; OrdSuperl a = { s = case a.isComp of { @@ -105,7 +110,7 @@ incomplete concrete NounScand of Noun = det = DIndef } ; - MassDet = {s = \\_,_ => [] ; n = Sg ; det = DIndef} ; + MassDet = {s = \\_,_,_ => [] ; n = Sg ; det = DIndef} ; UseN, UseN2, UseN3 = \noun -> { s = \\n,d,c => noun.s ! n ! specDet d ! c ; diff --git a/lib/resource/swedish/NumeralSwe.gf b/lib/resource/swedish/NumeralSwe.gf index 0885bb180..c44cb4b22 100644 --- a/lib/resource/swedish/NumeralSwe.gf +++ b/lib/resource/swedish/NumeralSwe.gf @@ -43,5 +43,41 @@ lin pot3plus n m = {s = \\g => n.s ! invNum ++ "tusen" ++ m.s ! g ; n = Pl} ; + lincat + Dig = TDigit ; + + lin + IDig d = d ; + + IIDig d i = { + s = \\o => d.s ! o ++ i.s ! o ; + n = Pl + } ; + + D_0 = mkDig "0" ; + D_1 = mk3Dig "1" "1a" Sg ; + D_2 = mk2Dig "2" "2a" ; + D_3 = mkDig "3" ; + D_4 = mkDig "4" ; + D_5 = mkDig "5" ; + D_6 = mkDig "6" ; + D_7 = mkDig "7" ; + D_8 = mkDig "8" ; + D_9 = mkDig "9" ; + + oper + mk2Dig : Str -> Str -> TDigit = \c,o -> mk3Dig c o Pl ; + mkDig : Str -> TDigit = \c -> mk2Dig c (c + "e") ; + + mk3Dig : Str -> Str -> Number -> TDigit = \c,o,n -> { + s = table {NCard _ => c ; NOrd _ => o} ; + n = n + } ; + + TDigit = { + n : Number ; + s : CardOrd => Str + } ; + } diff --git a/lib/resource/swedish/StructuralSwe.gf b/lib/resource/swedish/StructuralSwe.gf index 2cf7a9a83..7eb558d9a 100644 --- a/lib/resource/swedish/StructuralSwe.gf +++ b/lib/resource/swedish/StructuralSwe.gf @@ -29,7 +29,7 @@ concrete StructuralSwe of Structural = CatSwe ** everything_NP = regNP "allting" "alltings" SgNeutr ; everywhere_Adv = ss "överallt" ; few_Det = {s = \\_,_ => "få" ; n = Pl ; det = DDef Indef} ; - first_Ord = {s = "första" ; isDet = True} ; +--- first_Ord = {s = "första" ; isDet = True} ; for_Prep = ss "för" ; from_Prep = ss "från" ; he_Pron = MorphoSwe.mkNP "han" "honom" "hans" "hans" "hans" SgUtr P3 ; @@ -52,7 +52,7 @@ concrete StructuralSwe of Structural = CatSwe ** mkV "få" "måste" "få" "fick" "måst" "måst" ** {c2 = [] ; lock_VV = <>} ; no_Phr = ss ["nej"] ; on_Prep = ss "på" ; - one_Quant = {s = \\_ => genderForms ["en"] ["ett"] ; n = Sg ; det = DIndef} ; +--- one_Quant = {s = \\_ => genderForms ["en"] ["ett"] ; n = Sg ; det = DIndef} ; only_Predet = {s = \\_ => "bara"} ; or_Conj = ss "eller" ** {n = Sg} ; otherwise_PConj = ss "annars" ; diff --git a/src/GF/Devel/GrammarToGFCC.hs b/src/GF/Devel/GrammarToGFCC.hs index a61a2ec49..b7eaebe31 100644 --- a/src/GF/Devel/GrammarToGFCC.hs +++ b/src/GF/Devel/GrammarToGFCC.hs @@ -307,8 +307,8 @@ type ParamEnv = paramValues :: SourceGrammar -> ParamEnv paramValues cgr = (labels,untyps,typs) where partyps = nub $ - [App (Q (IC "Predef") (IC "Ints")) (EInt i) | i <- [1,9]] ---linTypeInt - ++ [ty | + --- [App (Q (IC "Predef") (IC "Ints")) (EInt i) | i <- [1,9]] ---linTypeInt + [ty | (_,(_,CncCat (Yes (RecType ls)) _ _)) <- jments, ty0 <- [ty | (_, ty) <- unlockTyp ls], ty <- typsFrom ty0 diff --git a/src/GF/GFCC/Linearize.hs b/src/GF/GFCC/Linearize.hs index d087384bf..7d5e6b010 100644 --- a/src/GF/GFCC/Linearize.hs +++ b/src/GF/GFCC/Linearize.hs @@ -31,8 +31,9 @@ linExp mcfg lang tree@(DTr _ at trees) = ---- bindings TODO case at of AC fun -> comp (lmap lin trees) $ look fun AS s -> R [kks (show s)] -- quoted - AI i -> R [C lst, kks (show i), C size] where - lst = mod (fromInteger i) 10 ; size = if i < 10 then 0 else 1 + AI i -> R [kks (show i)] + --- [C lst, kks (show i), C size] where + --- lst = mod (fromInteger i) 10 ; size = if i < 10 then 0 else 1 AF d -> R [kks (show d)] AM _ -> TM where diff --git a/src/GF/GFCC/Raw/ConvertGFCC.hs b/src/GF/GFCC/Raw/ConvertGFCC.hs index fbed72e69..3bfed9c83 100644 --- a/src/GF/GFCC/Raw/ConvertGFCC.hs +++ b/src/GF/GFCC/Raw/ConvertGFCC.hs @@ -73,7 +73,7 @@ toExp e = case e of App fun [App (CId "B") xs, App (CId "X") exps] -> DTr [x | AId x <- xs] (AC fun) (lmap toExp exps) App (CId "Eq") eqs -> - EEq [Equ (lmap toExp ps) (toExp v) | App (CId "Case") (v:ps) <- eqs] + EEq [Equ (lmap toExp ps) (toExp v) | App (CId "E") (v:ps) <- eqs] AMet -> DTr [] (AM 0) [] AInt i -> DTr [] (AI i) [] AFlt i -> DTr [] (AF i) [] @@ -147,7 +147,7 @@ fromExp e = case e of DTr [] (AI i) [] -> AInt (toInteger i) DTr [] (AM _) [] -> AMet ---- EEq eqs -> - App (CId "Eq") [App (CId "Case") (lmap fromExp (v:ps)) | Equ ps v <- eqs] + App (CId "Eq") [App (CId "E") (lmap fromExp (v:ps)) | Equ ps v <- eqs] _ -> error $ "exp " ++ show e fromTerm :: Term -> RExp diff --git a/src/GF/GFCC/doc/gfcc.txt b/src/GF/GFCC/doc/gfcc.txt index 6a78a62f6..5dcf2fbdc 100644 --- a/src/GF/GFCC/doc/gfcc.txt +++ b/src/GF/GFCC/doc/gfcc.txt @@ -1,6 +1,6 @@ The GFCC Grammar Format Aarne Ranta -October 5, 2007 +December 14, 2007 Author's address: [``http://www.cs.chalmers.se/~aarne`` http://www.cs.chalmers.se/~aarne] @@ -8,6 +8,7 @@ Author's address: % to compile: txt2tags -thtml --toc gfcc.txt History: +- 14 Dec 2007: simpler, Lisp-like concrete syntax of GFCC - 5 Oct 2007: new, better structured GFCC with full expressive power - 19 Oct: translation of lincats, new figures on C++ - 3 Oct 2006: first version @@ -53,7 +54,8 @@ will be used instead. GFC provides only marginal advantages as a target format compared with GF, and it is therefore just extra weight to carry around this format. -The main differences of GFCC compared with GFC (and GF) can be summarized as follows: +The main differences of GFCC compared with GFC (and GF) can be +summarized as follows: - there are no modules, and therefore no qualified names - a GFCC grammar is multilingual, and consists of a common abstract syntax together with one concrete syntax per language @@ -66,7 +68,8 @@ The main differences of GFCC compared with GFC (and GF) can be summarized as fol Here is an example of a GF grammar, consisting of three modules, -as translated to GFCC. The representations are aligned; thus they do not completely +as translated to GFCC. The representations are aligned; +thus they do not completely reflect the order of judgements in GFCC files, which have different orders of blocks of judgements, and alphabetical sorting. ``` diff --git a/src/GF/GFCC/doc/syntax.txt b/src/GF/GFCC/doc/syntax.txt new file mode 100644 index 000000000..6bb3b8d97 --- /dev/null +++ b/src/GF/GFCC/doc/syntax.txt @@ -0,0 +1,182 @@ +GFCC Syntax + + +==Syntax of GFCC files== + +The parser syntax is very simple, as defined in BNF: +``` + Grm. Grammar ::= [RExp] ; + + App. RExp ::= "(" CId [RExp] ")" ; + AId. RExp ::= CId ; + AInt. RExp ::= Integer ; + AStr. RExp ::= String ; + AFlt. RExp ::= Double ; + AMet. RExp ::= "?" ; + + terminator RExp "" ; + + token CId (('_' | letter) (letter | digit | '\'' | '_')*) ; +``` +While a parser and a printer can be generated for many languages +from this grammar by using the BNF Converter, a parser is also +easy to write by hand using recursive descent. + + +==Syntax of well-formed GFCC code== + +Here is a summary of well-formed syntax, +with a comment on the semantics of each construction. +``` + Grammar ::= + CId -- abstract syntax names + "(" "concrete" CId* ")" -- concrete syntax names + "(" "flags" Flag* ")" -- global flags + "(" "abstract" Abstract ")" -- abstract syntax + "(" "concrete" Concrete* ")" -- concrete syntaxes + + Abstract ::= + "(" "flags" Flag* ")" -- abstract flags + "(" "fun" FunDef* ")" -- function definitions + "(" "cat" CatDef* ")" -- category definitions + + Concrete ::= + "(" CId -- language name + "flags" Flag* -- concrete flags + "lin" LinDef* -- linearization rules + "oper" LinDef* -- operations (macros) + "lincat" LinDef* -- linearization type definitions + "lindef" LinDef* -- linearization default definitions + "printname" LinDef* -- printname definitions + "param" LinDef* -- lincats with labels and parameter value names + ")" + + Flag ::= "(" CId String ")" -- flag and value + FunDef ::= "(" CId Type Exp ")" -- function, type, and definition + CatDef ::= "(" CId Hypo* ")" -- category and context + LinDef ::= "(" CId Term ")" -- function and definition + + Type ::= + "(" CId -- value category + "(" "H" Hypo* ")" -- argument context + "(" "X" Exp* ")" ")" -- arguments (of dependent value type) + + Exp ::= + "(" CId -- function + "(" "B" CId* ")" -- bindings + "(" "X" Exp* ")" ")" -- arguments + | CId -- variable + | "?" -- metavariable + | "(" "Eq" Equation* ")" -- group of pattern equations + | Integer -- integer literal (non-negative) + | Float -- floating-point literal (non-negative) + | String -- string literal (in double quotes) + + Hypo ::= "(" CId Type ")" -- variable and type + + Equation ::= "(" "E" Exp Exp* ")" -- value and pattern list + + Term ::= + "(" "R" Term* ")" -- array (record or table) + | "(" "S" Term* ")" -- concatenated sequence + | "(" "FV" Term* ")" -- free variant list + | "(" "P" Term Term ")" -- access to index (projection or selection) + | "(" "W" String Term ")" -- token prefix with suffix list + | "(" "A" Integer ")" -- pointer to subtree + | String -- token (in double quotes) + | Integer -- index in array + | CId -- macro constant + | "?" -- metavariable +``` + + +==GFCC interpreter== + +The first phase in interpreting GFCC is to parse a GFCC file and +build an internal abstract syntax representation, as specified +in the previous section. + +With this representation, linearization can be performed by +a straightforward function from expressions (``Exp``) to terms +(``Term``). All expressions except groups of pattern equations +can be linearized. + +Here is a reference Haskell implementation of linearization: +``` + linExp :: GFCC -> CId -> Exp -> Term + linExp gfcc lang tree@(DTr _ at trees) = case at of + AC fun -> comp (map lin trees) $ look fun + AS s -> R [K (show s)] -- quoted + AI i -> R [K (show i)] + AF d -> R [K (show d)] + AM -> TM + where + lin = linExp gfcc lang + comp = compute gfcc lang + look = lookLin gfcc lang +``` +TODO: bindings must be supported. + +Terms resulting from linearization are evaluated in +call-by-value order, with two environments needed: +- the grammar (a concrete syntax) to give the global constants +- an array of terms to give the subtree linearizations + + +The Haskell implementation works as follows: +``` +compute :: GFCC -> CId -> [Term] -> Term -> Term +compute gfcc lang args = comp where + comp trm = case trm of + P r p -> proj (comp r) (comp p) + W s t -> W s (comp t) + R ts -> R $ map comp ts + V i -> idx args (fromInteger i) -- already computed + F c -> comp $ look c -- not computed (if contains V) + FV ts -> FV $ Prelude.map comp ts + S ts -> S $ Prelude.filter (/= S []) $ Prelude.map comp ts + _ -> trm + + look = lookOper gfcc lang + + idx xs i = xs !! i + + proj r p = case (r,p) of + (_, FV ts) -> FV $ Prelude.map (proj r) ts + (FV ts, _ ) -> FV $ Prelude.map (\t -> proj t p) ts + (W s t, _) -> kks (s ++ getString (proj t p)) + _ -> comp $ getField r (getIndex p) + + getString t = case t of + K (KS s) -> s + _ -> trace ("ERROR in grammar compiler: string from "++ show t) "ERR" + + getIndex t = case t of + C i -> fromInteger i + RP p _ -> getIndex p + TM -> 0 -- default value for parameter + _ -> trace ("ERROR in grammar compiler: index from " ++ show t) 0 + + getField t i = case t of + R rs -> idx rs i + RP _ r -> getField r i + TM -> TM + _ -> trace ("ERROR in grammar compiler: field from " ++ show t) t +``` +The result of linearization is usually a record, which is realized as +a string using the following algorithm. +``` + realize :: Term -> String + realize trm = case trm of + R (t:_) -> realize t + S ss -> unwords $ map realize ss + K s -> s + W s t -> s ++ realize t + FV (t:_) -> realize t -- TODO: all variants + TM -> "?" +``` +Notice that realization always picks the first field of a record. +If a linearization type has more than one field, the first field +does not necessarily contain the desired string. +Also notice that the order of record fields in GFCC is not necessarily +the same as in GF source. diff --git a/src/GF/Grammar/Lookup.hs b/src/GF/Grammar/Lookup.hs index 481512751..81a62decf 100644 --- a/src/GF/Grammar/Lookup.hs +++ b/src/GF/Grammar/Lookup.hs @@ -231,10 +231,10 @@ lookupAbsDef gr m c = errIn ("looking up absdef of" +++ prt c) $ do _ -> Bad $ prt m +++ "is not an abstract module" linTypeInt :: Type -linTypeInt = - let ints k = App (Q (IC "Predef") (IC "Ints")) (EInt k) in - RecType [ - (LIdent "last",ints 9),(LIdent "s", typeStr), (LIdent "size",ints 1)] +linTypeInt = defLinType +--- let ints k = App (Q (IC "Predef") (IC "Ints")) (EInt k) in +--- RecType [ +--- (LIdent "last",ints 9),(LIdent "s", typeStr), (LIdent "size",ints 1)] lookupLincat :: SourceGrammar -> Ident -> Ident -> Err Type lookupLincat gr m c | elem c [zIdent "Int"] = return linTypeInt