diff --git a/examples/letter/Letter.gf b/examples/letter/Letter.gf new file mode 100644 index 000000000..537750cb0 --- /dev/null +++ b/examples/letter/Letter.gf @@ -0,0 +1,83 @@ +abstract Letter = { + +--1 An Abstract Syntax for Business and Love Letters +-- +-- This file defines the abstract syntax of a grammar set whose concrete syntax +-- has so far been written to five languages: English, Finnish, French, Russian, +-- and Swedish. +-- +-- The main category of the grammar is $Letter$. The other categories are +-- parts of the letter. + +flags startcat=Letter ; + +cat + Letter ; + Recipient ; Author ; + Message ; + Heading ; Ending ; + Mode ; Sentence ; NounPhrase ; Position ; + +-- There is just one top-level letter structure. + +fun + MkLetter : Heading -> Message -> Ending -> Letter ; + +-- The heading consists of a greeting of the recipient. The $JustHello$ +-- function will actually suppress the name (and title) of the recipient, +-- but the $Recipient$ argument keeps track of the gender and number. + + DearRec : Recipient -> Heading ; + PlainRec : Recipient -> Heading ; + HelloRec : Recipient -> Heading ; + JustHello : Recipient -> Heading ; + +-- A message is a sentence with of without a *mode*, which is either +-- regret or honour. + + ModeSent : Mode -> Sentence -> Message ; + PlainSent : Sentence -> Message ; + + Honour, Regret : Mode ; + +-- The ending is either formal or informal. It does not currently depend on +-- the heading: making it so would eliminate formality mismatches between +-- the heading and the ending. + + FormalEnding : Author -> Ending ; + InformalEnding : Author -> Ending ; + +-- The recipient is either a colleague, colleagues, or darling. +-- It can also be a named person. The gender distinction is made +-- because there are things in the body of the letter that depend on it. + + ColleagueHe, ColleagueShe : Recipient ; + ColleaguesHe, ColleaguesShe : Recipient ; + DarlingHe, DarlingShe : Recipient ; + + NameHe, NameShe : String -> Recipient ; + +-- For the author, there is likewise a fixed set of titles, plus the named author. +-- Gender distinctions could be useful even here, for the same reason as with +-- $Recipient$. Notice that the rendering of $Spouse$ will depend on the +-- gender of the recipient. + + President, Mother, Spouse, Dean : Author ; + Name : String -> Author ; + +-- As for the message body, no much choice is yet available: one can say that +-- the recipient is promoted to some position, that someone has gone bankrupt, +-- or that the author loves the recipient. + + BePromoted : Position -> Sentence ; + GoBankrupt : NounPhrase -> Sentence ; + ILoveYou : Sentence ; + + Competitor : NounPhrase ; + Company : NounPhrase ; + OurCustomers : NounPhrase ; + + Senior : Position ; + ProjectManager : Position ; + +} diff --git a/examples/letter/LetterEng.gf b/examples/letter/LetterEng.gf new file mode 100644 index 000000000..5b57f0da7 --- /dev/null +++ b/examples/letter/LetterEng.gf @@ -0,0 +1,152 @@ +concrete LetterEng of Letter = { + +--1 An English Concrete Syntax for Business and Love Letters +-- +-- This file defines the English syntax of the grammar set +-- whose abstract syntax is $letter.Abs.gf$. + +flags lexer=textlit ; unlexer=textlit ; + +param Sex = masc | fem ; +param Num = sg | pl ; +param Kas = nom | acc ; +param DepNum = depnum | cnum Num ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Sex => Str} ; -- needs Num and Sex +lintype SSSrc = {s : Str ; n : Num ; x : Sex} ; -- gives Num and Sex +lintype SSSrc2 = {s : Num => Sex => Str ; n : DepNum ; x : Sex} ; -- gives and needs +lintype SSDep2 = {s : DepNum => Sex => Num => Sex => Str} ; -- needs Auth's & Recp's +lintype SSSrcNum = {s : Str ; n : Num} ; -- gives Num only + + +oper + ss : Str -> SS = \s -> {s = s} ; + constNX : Str -> Num -> Sex -> SSSrc2 = \str,num,sex -> + {s = table {_ => table {_ => str}} ; n = cnum num ; x = sex} ; + + dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum cn => cn + } ; + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcNum ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss (head.s ++ "," ++ "&-" ++ + mess.s ! end.n ! end.x ! head.n ! head.x ++ "." ++ "&-" ++ + end.s ! head.n ! head.x) ; + +DearRec rec = {s = "Dear" ++ rec.s ; n = rec.n ; x = rec.x} ; +PlainRec rec = rec ; +HelloRec rec = {s = "Hello" ++ rec.s ; n = rec.n ; x = rec.x} ; +JustHello rec = {s = "Hello" ; n = rec.n ; x = rec.x} ; + +ModeSent mode sent = + {s = + table {dna => table {xa => table {nr => table {xr => + mode.s ! dna ! xa ! nr ! xr ++ sent.s ! dna ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = table {n => table {x => + ["Sincerely yours &-"] ++ auth.s ! n ! x}} ; n = auth.n ; x = auth.x} ; +InformalEnding auth = + {s = table {n => table {x => + ["With best regards &-"] ++ auth.s ! n ! x}} ; n = auth.n ; x = auth.x} ; + +ColleaguesHe = {s = kollega ! pl ; n = pl ; x = masc} ; +ColleaguesShe = {s = kollega ! pl ; n = pl ; x = fem} ; +ColleagueHe = {s = kollega ! sg ; n = sg ; x = masc} ; +ColleagueShe = {s = kollega ! sg ; n = sg ; x = fem} ; +DarlingHe = {s = "darling" ; n = sg ; x = masc} ; +DarlingShe = {s = "darling" ; n = sg ; x = fem} ; +NameHe s = {s = s.s ; n = sg ; x = masc} ; +NameShe s = {s = s.s ; n = sg ; x = fem} ; + + +Honour = {s = + table {dna => table {xa => table {nr => table {xr => + let {na = dep2num dna nr} in + ego ! na ! nom ++ ["have the honour to inform you that"]}}}} + } ; + +Regret = {s = + table {dna => table {xa => table {nr => table {xr => + let {na = dep2num dna nr} in + ego ! na ! nom ++ am ! na ++ ["sorry to inform you that"]}}}} + } ; + + +President = constNX ["the President"] sg masc ; +Mother = constNX "Mom" sg fem ; +Spouse = {s = table { + sg => table {fem => ["your husband"] ; masc => ["your wife"]} ; + pl => table {fem => ["your husbands"] ; masc => ["your wives"]} + } ; n = depnum ; x = masc} ; -- sex does not matter here +Dean = constNX ["the Dean"] sg masc ; +Name s = constNX s.s sg masc ; --- + +BePromoted pos = {s = + table {na => table {xa => table {nr => table {xr => + ["you have been promoted to"] ++ + pos.s ! nr ! xr}}}} + } ; +GoBankrupt np = {s = + table {na => table {xa => table {nr => table {xr => + np.s ++ have ! np.n ++ ["gone bankrupt"]}}}} + } ; +ILoveYou = {s = + table {na => table {xa => table {nr => table {xr => + ego ! dep2num na nr ! nom ++ ["love you"]}}}} + } ; + +Company = {s = ["our company"] ; n = sg} ; +Competitor = {s = ["our worst competitor"] ; n = sg} ; +OurCustomers = {s = ["our customers"] ; n = pl} ; + +Senior = {s = + table { + sg => table {x => ["a senior fellow"]} ; + pl => table {x => ["senior fellows"]} + }} ; +ProjectManager = {s = + table { + sg => table {_ => ["a project manager"]} ; + pl => table {_ => ["project managers"]} + }} ; + +oper + +kollega : + Num => Str = + table {sg => "colleague" ; pl => "colleagues"} ; + +am : + Num => Str = + table {sg => "am" ; pl => "are"} ; + +have : + Num => Str = + table {sg => "has" ; pl => "have"} ; + +ego : + Num => Kas => Str = + table { + sg => table {nom => "I" ; acc => "me"} ; + pl => table {nom => "we" ; acc => "us"} + } ; + +} diff --git a/examples/letter/LetterFin.gf b/examples/letter/LetterFin.gf new file mode 100644 index 000000000..f7daa61a2 --- /dev/null +++ b/examples/letter/LetterFin.gf @@ -0,0 +1,180 @@ +concrete LetterFin of Letter = { + +--1 A Finnish Concrete Syntax for Business and Love Letters +-- +-- This file defines the Finnish syntax of the grammar set +-- whose abstract syntax is $letter.Abs.gf$. + +flags lexer=textlit ; unlexer=textlit ; + +-- modified from French in 20 min, 15/6/2002 + +param Gen = masc | fem ; +param Num = sg | pl ; +param Kas = nom | acc ; +param DepNum = depnum | cnum Num ; +param DepGen = depgen | cgen Gen ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Gen => Str} ; -- needs Num and Gen +lintype SSSrc = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen +lintype SSSrc2 = {s : Num => Gen => Str ; n : DepNum ; g : DepGen} ; -- gives&needs +lintype SSDep2 = {s : DepNum => DepGen => Num => Gen => Str} ; -- needs Auth's&Rec's +lintype SSSrcGen = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen + +oper + ss : Str -> SS = \s -> {s = s} ; + + noDep : (P : Type) -> Str -> P => Str = \_,s -> table {_ => s} ; + + cher : Num => Gen => Tok = + table {sg => noDep Gen "rakas" ; pl => noDep Gen "rakkaat"} ; + + egosum : Num => Str = + table {sg => "olen" ; pl => "olemme"} ; + egohabeo : Num => Str = + table {sg => "minulla" ++ "on" ; pl => "meill" ++ "on"} ; + fuisti : Num => Str = + table {sg => "sinut" ++ "on"; pl => "teidt" ++ "on"} ; + quePrep = "ett" ; ---- + tuinformare : Num => Str = + table {sg => "ilmoittaa" ++ "sinulle" ; pl => "ilmoittaa" ++ "teille"} ; + + regNom : Str -> Num => Str = \pora -> table {sg => pora ; pl => pora + "t"} ; + + avoir : Num => Str = + table {sg => "on"; pl => "ovat"} ; + + mes : Num => Str = table {sg => "minun" ; pl => "meidn"} ; + + teamo : Num => Num => Str = table { + sg => table {sg => "rakastan" ++ "sinua" ; + pl => "rakastan" ++ "teit"} ; + pl => table {sg => "rakastamme" ++ "sinua" ; + pl => "rakastamme" ++ "teit"} + } ; + + constNG : Str -> Num -> Gen -> SSSrc2 = \str,num,gen -> + {s = table {_ => table {_ => str}} ; n = cnum num ; g = cgen gen} ; + + dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum cn => cn + } ; + dep2gen : DepGen -> Gen -> Gen = \dg,g -> case dg of { + depgen => case g of { + masc => fem ; + fem => masc + }; -- negative dependence: the author is of opposite sex + cgen cg => cg + } ; + + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcGen ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss (head.s ++ "," ++ "&-" ++ + mess.s ! end.n ! end.g ! head.n ! head.g ++ "." ++ "&-" ++ + end.s ! head.n ! head.g) ; + +DearRec rec = {s = cher ! rec.n ! rec.g ++ rec.s ; n = rec.n ; g = rec.g} ; +PlainRec rec = rec ; +HelloRec rec = {s = "Terve" ++ rec.s ; n = rec.n ; g = rec.g} ; +JustHello rec = {s = "Terve" ; n = rec.n ; g = rec.g} ; + +ModeSent mode sent = + {s = + table {na => table {xa => table {nr => table {xr => + mode.s ! na ! xa ! nr ! xr ++ sent.s ! na ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = table {n => table {g => ["parhain terveisin &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; +InformalEnding auth = + {s = table {n => table {g => ["terveisin &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; + +ColleaguesHe = {s = regNom "kollega" ! pl ; n = pl ; g = masc} ; +ColleaguesShe = {s = regNom "kollega" ! pl ; n = pl ; g = fem} ; +ColleagueHe = {s = regNom "kollega" ! sg ; n = sg ; g = masc} ; +ColleagueShe = {s = regNom "kollega" ! sg ; n = sg ; g = fem} ; +DarlingHe = {s = "kulta" ; n = sg ; g = masc} ; +DarlingShe = {s = "kulta" ; n = sg ; g = fem} ; +NameHe s = {s = s.s ; n = sg ; g = masc} ; +NameShe s = {s = s.s ; n = sg ; g = fem} ; + + +Honour = {s = + table {na => table {xa => table {nr => table {xr => + egohabeo ! dep2num na nr ++ + ["kunnia"] ++ tuinformare ! nr ++ quePrep}}}} + } ; + +Regret = {s = + table {na => table {ga => table {nr => table {gr => + mes ! dep2num na nr ++ + ["on valitettavasti ilmoitettava"] ++ quePrep}}}} + } ; + + +President = constNG ["presidentti"] sg masc ; +Mother = constNG ["iti"] sg fem ; +Spouse = {s = table { + sg => table {fem => ["miehesi"] ; masc => ["vaimosi"]} ; + pl => table {fem => ["miehenne"] ; masc => ["vaimonne"]} + } ; n = depnum ; g = depgen} ; +Dean = constNG ["dekaani"] sg masc ; +Name s = constNG s.s sg masc ; --- + +BePromoted pos = {s = + table {na => table {xa => table {nr => table {xr => + fuisti ! nr ++ "ylennetty" ++ + pos.s ! nr ! xr}}}} + } ; +GoBankrupt np = {s = + table {na => + table {xa => + table {nr => + table {xr => + np.s ++ avoir ! np.n ++ + (case np.n of {sg => "mennyt" ; pl => "menneet"}) ++ + "konkurssiin" + } + } + } + } + } ; + +ILoveYou = {s = + table {na => table {xa => table {nr => table {xr => + teamo ! dep2num na nr ! nr}}}}} ; + +Company = {s = ["yrityksemme"] ; n = sg ; g = fem} ; +Competitor = {s = ["pahin kilpailijamme"] ; n = sg ; g = masc} ; +OurCustomers = {s = ["asiakkaamme"] ; n = pl ; g = masc} ; + +Senior = {s = table {sg => table {g => ["vanhemmaksi tutkijaksi"]} ; + pl => table {g => ["vanhemmiksi tutkijoiksi"]} + } + } ; + +ProjectManager = {s = + table { + sg => table {_ => ["projektipllikksi"]} ; + pl => table {_ => ["projektipllikiksi"]} + }} ; + +} diff --git a/examples/letter/LetterFre.gf b/examples/letter/LetterFre.gf new file mode 100644 index 000000000..0755a99a0 --- /dev/null +++ b/examples/letter/LetterFre.gf @@ -0,0 +1,170 @@ +concrete LetterFre of Letter = { + +--1 An French Concrete Syntax for Business and Love Letters +-- +-- This file defines the French syntax of the grammar set +-- whose abstract syntax is $letter.Abs.gf$. + + +flags lexer=textlit ; unlexer=textlit ; + +param Gen = masc | fem ; +param Num = sg | pl ; +param Kas = nom | acc ; +param DepNum = depnum | cnum Num ; +param DepGen = depgen | cgen Gen ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Gen => Str} ; -- needs Num and Gen +lintype SSSrc = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen +lintype SSSrc2 = {s : Num => Gen => Str ; n : DepNum ; g : DepGen} ; -- gives&needs +lintype SSDep2 = {s : DepNum => DepGen => Num => Gen => Str} ; -- needs Auth's&Rec's +lintype SSSrcGen = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen + +oper + ss : Str -> SS = \s -> {s = s} ; + cher : Num => Gen => Tok = + table {n => table {masc => regNom "cher" ! n ; fem => regNom "chre" ! n}}; + regAdj : Str -> Gen => Num => Str = \s -> + table {masc => regNom s ; fem => regNom (s + "e")} ; + regNom : Str -> Num => Str = \s -> table {sg => s ; pl => s + "s"} ; + egosum : Num => Str = + table {sg => "je" ++ "suis" ; pl => "nous" ++ "sommes"} ; + egohabeo : Num => Str = + table {sg => "j'ai" ; pl => "nous" ++ "avons"} ; + fuisti : Num => Str = + table {sg => "tu" ++ "as" ++ "t"; pl => "vous" ++ "avez" ++ "t"} ; + quePrep = "que" ; ---- + tuinformare : Num => Str = + table {sg => "t'informer"; pl => "vous" ++ "informer"} ; + + avoir : Num => Str = + table {sg => "a"; pl => "ont"} ; + + mes : Num => Str = table {sg => "mes" ; pl => "nos"} ; + + teamo : Num => Num => Str = table { + sg => table {sg => "je" ++ "t'aime" ; + pl => "je" ++ "vous" ++ "aime"} ; + pl => table {sg => "nous" ++ "t'aimons" ; + pl => "nous" ++ "vous" ++ "aimons"} + } ; + + constNG : Str -> Num -> Gen -> SSSrc2 = \str,num,gen -> + {s = table {_ => table {_ => str}} ; n = cnum num ; g = cgen gen} ; + + dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum sg => sg ; + cnum pl => pl + } ; + dep2gen : DepGen -> Gen -> Gen = \dg,g -> case dg of { + depgen => case g of { + masc => fem ; + fem => masc + }; -- negative dependence: the author is of opposite sex + cgen cg => cg + } ; + + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcGen ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss (head.s ++ "," ++ "&-" ++ + mess.s ! end.n ! end.g ! head.n ! head.g ++ "." ++ "&-" ++ + end.s ! head.n ! head.g) ; + +DearRec rec = {s = cher ! rec.n ! rec.g ++ rec.s ; n = rec.n ; g = rec.g} ; +PlainRec rec = rec ; +HelloRec rec = {s = "Bonjour" ++ rec.s ; n = rec.n ; g = rec.g} ; +JustHello rec = {s = "Bonjour" ; n = rec.n ; g = rec.g} ; + +ModeSent mode sent = + {s = + table {na => table {xa => table {nr => table {xr => + mode.s ! na ! xa ! nr ! xr ++ sent.s ! na ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = + table {n => table {g => + "avec" ++ mes ! dep2num auth.n n ++ + ["salutations distingues &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; +InformalEnding auth = + {s = table {n => table {g => ["Amicalement &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; + +ColleaguesHe = {s = regNom "collgue" ! pl ; n = pl ; g = masc} ; +ColleaguesShe = {s = regNom "collgue" ! pl ; n = pl ; g = fem} ; +ColleagueHe = {s = regNom "collgue" ! sg ; n = sg ; g = masc} ; +ColleagueShe = {s = regNom "collgue" ! sg ; n = sg ; g = fem} ; +DarlingHe = {s = "chri" ; n = sg ; g = masc} ; +DarlingShe = {s = "chrie" ; n = sg ; g = fem} ; +NameHe s = {s = s.s ; n = sg ; g = masc} ; +NameShe s = {s = s.s ; n = sg ; g = fem} ; + +Honour = {s = + table {na => table {xa => table {nr => table {xr => + egohabeo ! dep2num na nr ++ + ["l'honneur de"] ++ tuinformare ! nr ++ quePrep}}}} + } ; + +Regret = {s = + table {na => table {ga => table {nr => table {gr => + let {dga = dep2gen ga gr ; dna = dep2num na nr} in + egosum ! dna ++ regAdj "dsol" ! dga ! dna ++ + ["d'informer"] ++ quePrep}}}} + } ; + + +President = constNG ["le prsident"] sg masc ; +Mother = constNG ["maman"] sg fem ; +Spouse = {s = table { + sg => table {fem => ["ton mari"] ; masc => ["ta femme"]} ; + pl => table {fem => ["vos maris"] ; masc => ["vos femmes"]} + } ; n = depnum ; g = depgen} ; +Dean = constNG ["le doyen"] sg masc ; +Name s = constNG s.s sg masc ; --- + +BePromoted pos = {s = + table {na => table {xa => table {nr => table {xr => + fuisti ! nr ++ regAdj "promu" ! xr ! nr ++ + pos.s ! nr ! xr}}}} + } ; +GoBankrupt np = {s = + table {na => table {xa => table {nr => table {xr => + np.s ++ avoir ! np.n ++ ["fait banqueroute"]}}}} + } ; +ILoveYou = {s = + table {na => table {xa => table {nr => table {xr => + teamo ! dep2num na nr ! nr}}}} + } ; + +Company = {s = ["notre entreprise"] ; n = sg ; g = fem} ; +Competitor = {s = ["notre pire comptiteur"] ; n = sg ; g = masc} ; +OurCustomers = {s = ["nos clients"] ; n = pl ; g = masc} ; + +Senior = {s = table {sg => table {g => ["responsable scientifique"]} ; + pl => table {g => ["responsables scientifiques"]} + } + } ; + +ProjectManager = {s = + table { + sg => table {_ => ["chef de projet"]} ; + pl => table {_ => ["chefs de projets"]} + }} ; +} diff --git a/examples/letter/LetterHeb.gf b/examples/letter/LetterHeb.gf new file mode 100644 index 000000000..40d411e5e --- /dev/null +++ b/examples/letter/LetterHeb.gf @@ -0,0 +1,213 @@ +concrete LetterHeb of Letter = { + +-- (c) Alex Kutsela 2005 + +flags lexer=textlit ; unlexer=textlit ; coding=utf8 ; + +param Gen = masc | fem ; +param Num = sg | pl ; +param Kas = nom | dat | acc ; +param DepNum = depnum | cnum Num ; +param DepGen = depgen | cgen Gen ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Gen => Str} ; -- needs Num and Gen +lintype SSSrc = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen +lintype SSSrc2 = {s : Num => Gen => Str ; n : DepNum ; g : DepGen} ; -- gives&needs +lintype SSDep2 = {s : DepNum => DepGen => Num => Gen => Str} ; -- needs Auth's&Rec's +lintype SSSrcGen = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen + +oper + ss : Str -> SS = \s -> {s = s} ; + regAdj : Str -> Num => Gen => Tok =\s -> table { + sg => table {masc => s; fem => s+"ה"}; + pl => table {masc => s+"ים"; fem => s+"ות"} + }; + +hello : Str -> Num => Str = \s -> table {sg => s ; pl => s} ; + +regVerPerf : Str -> Num => Gen => Str = \s -> + table {sg => table {masc => s; fem => s+"ה"}; + pl => table {masc => s+"ו"; fem => s+"ו"} + }; + +ego : Num => Str = table {sg => "אןי" ; pl => "אןחןו" } ; + +tu : Num => Gen => Kas => Str = + table {sg => table {fem => table {nom => "את"; dat => "לך"; acc => "אותך"} ; + masc => table {nom => "אתה"; dat => "לך"; acc => "אותך"} + } ; + pl => table {fem => table {nom => "אתן"; dat => "לכן"; acc => "אתכן"} ; + masc => table {nom => "אתם"; dat => "לכם"; acc => "אתכם"} + } + }; + +hereIam : Num => Str = + table {sg => "הןןי" ; pl => "הןןו" } ; + +haveBeen : Str -> Num => Gen => Str = \s -> + table {sg => table {masc => s+"ת"; fem => s+"ת"}; + pl => table {masc => s+"תם"; fem => s+"תן"} + }; + +thatConj = ["ש"] ; + +regVer : Str -> Num => Gen => Str = \s -> + table {sg => table {masc => s; fem => s+"ת"}; + pl => table {masc => s+"ים"; fem => s+"ות"} + }; + +constNG : Str -> Num -> Gen -> SSSrc2 = \str,num,gen -> + {s = table {_ => table {_ => str}} ; n = cnum num ; g = cgen gen} ; + +dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum cn => cn + } ; +dep2gen : DepGen -> Gen -> Gen = \dg,g -> case dg of { + depgen => case g of { + masc => fem ; + fem => masc + }; -- negative dependence: the author is of opposite sex + cgen cg => cg + } ; + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcGen ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss ("," ++ head.s ++ "&-" ++ + mess.s ! end.n ! end.g ! head.n ! head.g ++ "&-" ++ + end.s ! head.n ! head.g) ; + +DearRec rec = {s = rec.s ++ regAdj "יקר" ! rec.n ! rec.g; + n = rec.n; + g = rec.g}; +PlainRec rec = rec ; +HelloRec rec = {s = hello "שלום" ! rec.n ++ rec.s ; n = rec.n ; g = rec.g} ; +JustHello rec = {s = hello "שלום" ! rec.n ; n = rec.n ; g = rec.g} ; + +ModeSent mode sent = + {s = + table {na => table {xa => table {nr => table {xr => + mode.s ! na ! xa ! nr ! xr ++ sent.s ! na ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = + table {n => table {g => + [",בכבוד רב &-"] ++ + auth.s ! n ! g + }} ; + n = auth.n ; g = auth.g} ; + +InformalEnding auth = + {s = table {n => table {g => [",בברכה &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; + +ColleagueHe = {s = "עמית" ; n = sg ; g = masc} ; +ColleagueShe = {s = "עמיתה" ; n = sg ; g = fem} ; +ColleaguesHe = {s = "עמיתים" ; n = pl ; g = masc} ; +ColleaguesShe = {s = "עמיתות" ; n = pl ; g = fem} ; +DarlingHe = {s = "אהובי" ; n = sg ; g = masc} ; +DarlingShe = {s = "אהובתי" ; n = sg ; g = fem} ; + +NameHe s = {s = s.s ; n = sg ; g = masc} ; +NameShe s = {s = s.s ; n = sg ; g = fem} ; + +Honour = {s = table { + na => table { + xa => table { + nr => table { + xr => hereIam ! dep2num na nr ++ + regVer "מתכבד" ! dep2num na nr ! dep2gen xa xr ++ + ["להודיע"] ++ tu ! nr ! xr ! dat ++ thatConj + } + } + } + } + } ; + +Regret = {s = table { + na => table { + ga => table { + nr => table { + gr => let {dga = dep2gen ga gr ; dna = dep2num na nr} in + ego ! dna ++ regVer "מצטער" ! dna ! dga ++ + ["להודיע"] ++ tu ! nr ! gr ! dat ++ thatConj + } + } + } + } + } ; + +Dean = constNG ["דיקן"] sg masc ; +President = constNG ["ןשיא"] sg masc ; +Mother = constNG ["אמא"] sg fem ; +Name s = constNG s.s sg masc ; --- +Spouse = {s = table { + sg => table {fem => ["בעלך"] ; masc => ["אישתך"]} ; + pl => table {fem => ["בעליכן"] ; masc => ["ןשותיכם"]} + } ; n = depnum ; g = depgen} ; + +BePromoted pos = {s = table { + na => table { + xa => table { + nr => table { + xr => haveBeen "קודמ" ! nr !xr ++ "לתפקיד" ++ "של" ++ pos.s ! nr ! xr + } + } + } + } + } ; + +GoBankrupt np = + {s = table + {na => table + {xa => table + {nr => table + {xr => np.s ++ regVerPerf "פשט" ! np.n ! np.g ++ "רגל"} + } + } + } + } ; + +ILoveYou = {s = table + {na => table + {ga => table + {nr => table + {gr => let {dga = dep2gen ga gr ; dna = dep2num na nr} in + ego ! dna ++ regVer "אוהב" ! dna ! dga ++ + tu ! nr ! gr ! acc} + } + } + } + } ; + +Company = {s = ["חברתןו"] ; n = sg ; g = fem} ; +Competitor = {s = ["המתחרה הגרוע ביותר שלןו"] ; n = sg ; g = masc} ; +OurCustomers = {s = ["לקוחותיןו"] ; n = pl ; g = masc} ; + +Senior = {s = table + {sg => table {g => ["חבר בכיר"]} ; + pl => table {g => ["חברים בכירים"]} + } + } ; + +ProjectManager = {s = table { + sg => table {fem => ["מןהלת פרוייקט"]; masc => ["מןהל פרוייקט"]} ; + pl => table {fem => ["מןהלות פרוייקט"]; mask =>["מןהלי פרוייקט"]} + } + } ; +} diff --git a/examples/letter/LetterRus.gf b/examples/letter/LetterRus.gf new file mode 100644 index 000000000..b5f7434e9 --- /dev/null +++ b/examples/letter/LetterRus.gf @@ -0,0 +1,177 @@ +concrete LetterRus of Letter = { + +flags lexer=textlit ; unlexer=textlit ; coding=utf8 ; + +param Gen = masc | fem ; +param Num = sg | pl ; +param Kas = nom | acc ; +param DepNum = depnum | cnum Num ; +param DepGen = depgen | cgen Gen ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Gen => Str} ; -- needs Num and Gen +lintype SSSrc = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen +lintype SSSrc2 = {s : Num => Gen => Str ; n : DepNum ; g : DepGen} ; -- gives&needs +lintype SSDep2 = {s : DepNum => DepGen => Num => Gen => Str} ; -- needs Auth's&Rec's +lintype SSSrcGen = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen + +oper + ss : Str -> SS = \s -> {s = s} ; + regAdj : Str -> Num => Gen => Tok =\s -> table { + sg => table {masc => s+"ой"; fem => s+"ая"}; + pl => table {masc => s+"ие"; fem => s+"ие"} + }; + regVer : Str -> Num => Gen => Str = \s -> table { + sg => table {masc => s; fem => s+"а"}; + pl => table {masc => s+"ы"; fem => s+"ы"} + }; + + hello : Str -> Num => Str = \s -> + table {sg => s ; pl => s+"те" } ; + + regVerPerf : Str -> Num => Gen => Str = \s -> table { + sg => table {masc => s+"ся"; fem => s+"ось"}; + pl => table {masc => s+"ись"; fem => s+"ись"} + }; + + ego : Num => Str = + table {sg => "я" ; pl => "вы" } ; + egoHave : Num => Str = + table {sg => ["я имею"] ; pl => ["мы имеем"]} ; + + haveBeen : Num => Gen => Str = table { + sg => table {masc => ["ты был"] ; fem => ["ты была"] }; + pl => table {masc => ["вы были"]; fem => ["вы были"]} + }; + + thatPrep = [", что"] ; + informYou : Num => Str = + table {sg => ["сообщить тебе"]; pl => ["сообщить вам"]} ; + + loveYou : Num => Num => Str = table { + sg => table {sg => ["я тебя люблю"] ; + pl => ["я вас люблю"]} ; + pl => table {sg => ["мы тебя любим"] ; + pl => ["мы вас любим"]} + } ; + + constNG : Str -> Num -> Gen -> SSSrc2 = \str,num,gen -> + {s = table {_ => table {_ => str}} ; n = cnum num ; g = cgen gen} ; + + dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum cn => cn + } ; + dep2gen : DepGen -> Gen -> Gen = \dg,g -> case dg of { + depgen => case g of { + masc => fem ; + fem => masc + }; -- negative dependence: the author is of opposite sex + cgen cg => cg + } ; + + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcGen ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss (head.s ++ "," ++ "&-" ++ + mess.s ! end.n ! end.g ! head.n ! head.g ++ "." ++ "&-" ++ + end.s ! head.n ! head.g) ; + +DearRec rec = {s = regAdj "Дорог" + ! rec.n ! rec.g ++ rec.s ; n = rec.n ; g = rec.g} ; +PlainRec rec = rec ; +HelloRec rec = {s = hello "Здравствуй" ! rec.n ++ rec.s ; n = rec.n ; g = rec.g} ; +JustHello rec = {s = hello "Здравствуй" ! rec.n ; n = rec.n ; g = rec.g} ; + +ModeSent mode sent = + {s = + table {na => table {xa => table {nr => table {xr => + mode.s ! na ! xa ! nr ! xr ++ sent.s ! na ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = + table {n => table {g => + "С" ++ + ["наилучшими пожеланиями, &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; +InformalEnding auth = + {s = table {n => table {g => ["С дружеским приветом, &-"] ++ auth.s ! n ! g}} ; + n = auth.n ; g = auth.g} ; + +ColleaguesHe = {s = "коллеги" ; n = pl ; g = masc} ; +ColleaguesShe = {s = "коллеги" ; n = pl ; g = fem} ; +ColleagueHe = {s = "коллега" ; n = sg ; g = masc} ; +ColleagueShe = {s = "коллега" ; n = sg ; g = fem} ; +DarlingHe = {s = "любимый" ; n = sg ; g = masc} ; +DarlingShe = {s = "любимая" ; n = sg ; g = fem} ; +NameHe s = {s = s.s ; n = sg ; g = masc} ; +NameShe s = {s = s.s ; n = sg ; g = fem} ; + + +Honour = {s = + table {na => table {xa => table {nr => table {xr => + egoHave ! dep2num na nr ++ + ["честь"] ++ informYou ! nr ++ thatPrep}}}} + } ; + +Regret = {s = + table {na => table {ga => table {nr => table {gr => + let {dga = dep2gen ga gr ; dna = dep2num na nr} in + ego ! dna ++ regVer "вынужден" ! dna ! dga ++ + ["сообщить"] ++ thatPrep}}}} + } ; + + +President = constNG ["президент"] sg masc ; +Mother = constNG ["мама"] sg fem ; +Spouse = {s = table { + sg => table {fem => ["твой муж"] ; masc => ["твоя жена"]} ; + pl => table {fem => ["ваши мужья"] ; masc => ["ваши жены"]} + } ; n = depnum ; g = depgen} ; +Dean = constNG ["декан"] sg masc ; +Name s = constNG s.s sg masc ; --- + +BePromoted pos = {s = + table {na => table {xa => table {nr => table {xr => + haveBeen ! nr ! xr ++ regVer "назначен" ! nr ! xr ++ + pos.s ! nr ! xr}}}} + } ; +GoBankrupt np = {s = + table {na => table {xa => table {nr => table {xr => + np.s ++ regVerPerf "обанкротил" ! np.n ! np.g }}}} + } ; +ILoveYou = {s = + table {na => table {xa => table {nr => table {xr => + loveYou ! dep2num na nr ! nr}}}} + } ; + +Company = {s = ["наше предприятие"] ; n = sg ; g = fem} ; +Competitor = {s = ["наш конкурент"] ; n = sg ; g = masc} ; +OurCustomers = {s = ["наши клиенты"] ; n = pl ; g = masc} ; + +Senior = {s = table {sg => table {g => ["старшим научным сотрудником"]} ; + pl => table {g =>[ "старшими научными сотрудниками"]} + } + } ; + +ProjectManager = {s = + table { + sg => table {_ => ["менеджером проекта"]} ; + pl => table {_ => ["менеджерами проектов"]} + }} ; + +} diff --git a/examples/letter/LetterSwe.gf b/examples/letter/LetterSwe.gf new file mode 100644 index 000000000..e7bcd433d --- /dev/null +++ b/examples/letter/LetterSwe.gf @@ -0,0 +1,162 @@ +concrete LetterSwe of Letter = { + +--1 An Swedish Concrete Syntax for Business and Love Letters +-- +-- This file defines the Swedish syntax of the grammar set +-- whose abstract syntax is $letter.Abs.gf$. + + +flags lexer=textlit ; unlexer=textlit ; + +printname Letter = "Brev" ; +printname MkLetter = "brevmall" ; + +param Sex = masc | fem ; +param Gen = en | ett ; +param Num = sg | pl ; +param Kas = nom | acc ; +param DepNum = depnum | cnum Num ; + +lintype SS = {s : Str} ; +lintype SSDep = {s : Num => Sex => Str} ; -- needs Num and Sex +lintype SSSrc = {s : Str ; n : Num ; x : Sex} ; -- gives Num and Sex +lintype SSSrc2 = {s : Num => Sex => Str ; n : DepNum ; x : Sex} ; -- gives and needs +lintype SSDep2 = {s : DepNum => Sex => Num => Sex => Str} ; -- needs Auth's & Recp's +lintype SSSrcGen = {s : Str ; n : Num ; g : Gen} ; -- gives Num and Gen + + +oper + ss : Str -> SS = \s -> {s = s} ; + + constNX : Str -> Num -> Sex -> SSSrc2 = \str,num,sex -> + {s = table {_ => table {_ => str}} ; n = cnum num ; x = sex} ; + + dep2num : DepNum -> Num -> Num = \dn,n -> case dn of { + depnum => n ; + cnum cn => cn + } ; + +lincat +Letter = SS ; +Recipient = SSSrc ; +Author = SSSrc2 ; +Message = SSDep2 ; +Heading = SSSrc ; +Ending = SSSrc2 ; +Mode = SSDep2 ; +Sentence = SSDep2 ; +NounPhrase = SSSrcGen ; +Position = SSDep ; + +lin +MkLetter head mess end = + ss (head.s ++ "," ++ "&-" ++ + mess.s ! end.n ! end.x ! head.n ! head.x ++ "." ++ "&-" ++ + end.s ! head.n ! head.x) ; + +DearRec rec = {s = kaer ! rec.n ! rec.x ++ rec.s ; n = rec.n ; x = rec.x} ; +PlainRec rec = rec ; +HelloRec rec = {s = "Hej" ++ rec.s ; n = rec.n ; x = rec.x} ; +JustHello rec = {s = "Hej" ; n = rec.n ; x = rec.x} ; + +ModeSent mode sent = + {s = + table {na => table {xa => table {nr => table {xr => + mode.s ! na ! xa ! nr ! xr ++ sent.s ! na ! xa ! nr ! xr}}}} + } ; +PlainSent sent = sent ; + +FormalEnding auth = + {s = table {n => table {x => + ["Med vnlig hlsning &-"] ++ auth.s ! n ! x}} ; n = auth.n ; x = auth.x} ; + +InformalEnding auth = + {s = table {n => table {x => + ["Med hlsningar &-"] ++ auth.s ! n ! x}} ; n = auth.n ; x = auth.x} ; + +ColleaguesHe = {s = kollega ! pl ; n = pl ; x = masc} ; +ColleaguesShe = {s = kollega ! pl ; n = pl ; x = fem} ; +ColleagueHe = {s = kollega ! sg ; n = sg ; x = masc} ; +ColleagueShe = {s = kollega ! sg ; n = sg ; x = fem} ; +DarlingHe = {s = "lskling" ; n = sg ; x = masc} ; +DarlingShe = {s = "lskling" ; n = sg ; x = fem} ; +NameHe s = {s = s.s ; n = sg ; x = masc} ; +NameShe s = {s = s.s ; n = sg ; x = fem} ; + +Honour = {s = + table {na => table {xa => table {nr => table {xr => + jag ! dep2num na nr ! nom ++ ["har ran att meddela"] ++ + du ! nr ! acc ++ "att"}}}} + } ; + +Regret = {s = + table {na => table {xa => table {nr => table {xr => + jag ! dep2num na nr ! nom ++ ["mste tyvrr meddela"] ++ + du ! nr ! acc ++ "att"}}}} + } ; + + +President = constNX ["Presidenten"] sg masc ; +Mother = constNX ["Mamma"] sg fem ; +Spouse = {s = table { + sg => table {fem => ["din man"] ; masc => ["din hustru"]} ; + pl => table {fem => ["era mn"] ; masc => ["era hustrur"]} + } ; n = depnum ; x = masc} ; -- sex does not matter here +Dean = constNX ["Dekanus"] sg masc ; +Name s = constNX s.s sg masc ; --- + +BePromoted pos = {s = + table {na => table {xa => table {nr => table {xr => + du ! nr ! nom ++ ["har blivit"] ++ befordrad ! nr ++ + "till" ++ pos.s ! nr ! xr}}}} + } ; +GoBankrupt np = {s = + table {na => table {xa => table {nr => table {xr => + np.s ++ ["har gtt i konkurs"]}}}} + } ; +ILoveYou = {s = + table {na => table {xa => table {nr => table {xr => + jag ! dep2num na nr ! nom ++ ["lskar"] ++ du ! nr ! acc}}}} + } ; + +Company = {s = ["vrt fretag"] ; n = sg ; g = ett} ; +Competitor = {s = ["vr vrsta konkurrent"] ; n = sg ; g = en} ; +OurCustomers = {s = ["vra kunder"] ; n = pl ; g = en} ; + +Senior = {s = table {n => table {x => ["ldre forskare"]}}} ; +ProjectManager = {s = + table { + sg => table {_ => "projektchef"} ; + pl => table {_ => "projektchefer"} + }} ; + +oper + +kaer : + Num => Sex => Str = + table { + sg => table {masc => "Kre" ; fem => "Kra"} ; + pl => table {_ => "Kra"} + } ; + +kollega : + Num => Str = + table {sg => "kollega" ; pl => "kollegor"} ; + +befordrad : + Num => Str = + table {sg => "befordrad" ; pl => "befordrade"} ; + +jag : + Num => Kas => Str = + table { + sg => table {nom => "jag" ; acc => "mig"} ; + pl => table {nom => "vi" ; acc => "oss"} + } ; +du : + Num => Kas => Str = + table { + sg => table {nom => "du" ; acc => "dig"} ; + pl => table {nom => "ni" ; acc => "er"} + } ; +} diff --git a/examples/letter/README b/examples/letter/README new file mode 100644 index 000000000..d1691f721 --- /dev/null +++ b/examples/letter/README @@ -0,0 +1,35 @@ +GF challenges Microsoft Works! Here you find templates for +multilingual authoring of business and love letters! + +Another point of these grammars is to illustrate how +local updates are propagated everywhere in the document. +Form, in the editor + + Dear Colleague, + + I love you. + + With best regards, + + your wife + +and change between ColleagueHe, ColleagueShe, ColleaguesHe, ColleaguesShe. + +The grammars are somewhat ad hoc and messy, and could be improved +with better abstractions. + +(AR 2001) + +To use the grammars in an editor, first compile them to javascript: + + gfc --make --output-format=js Letter???.gf + +Then open the file ./editor/editor.html in a web browser. You also need the javascript +libraries from + + GF/lib/javascript/ + +Copyright (c) 2001-2008 Janna Khegai, Alex Kutsela, Aarne Ranta +under GNU General Public License (GPL). + +Document last updated December 4, 2008, by Aarne Ranta. diff --git a/examples/letter/editor/editor.html b/examples/letter/editor/editor.html new file mode 100644 index 000000000..5c9aa4fc5 --- /dev/null +++ b/examples/letter/editor/editor.html @@ -0,0 +1,17 @@ + + + +
+ + + + + + +