mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 04:59:31 -06:00
took back smart type of Int ; Digits type in resource and some adjustments of Det syntax (not yet for romance and russian)
This commit is contained in:
@@ -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"
|
||||
|
||||
}
|
||||
|
||||
@@ -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].
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
}
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
<n.size,n.last>
|
||||
} ;
|
||||
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)
|
||||
-- ---- <n.size,n.last>
|
||||
-- } ;
|
||||
|
||||
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 ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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" ;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
```
|
||||
|
||||
182
src/GF/GFCC/doc/syntax.txt
Normal file
182
src/GF/GFCC/doc/syntax.txt
Normal file
@@ -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.
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user