Ticket #2 (new enhancement)

Opened 6 years ago

New EBNF syntax

Reported by: PeterLjunglof Owned by: PeterLjunglof
Priority: major Version:
Keywords: Cc:

Description

Note: This is an old suggestion described in Swedish, sorry for that.

	Från: 	peb@ling.gu.se
	Ämne: 	Lite ny GF-syntax...
	Datum: 	fr 17 aug 2007 12.56.48 GMT+02:00
	Till: 	aarne@cs.chalmers.se, bringert@cs.chalmers.se

Hej på er,

tillbaka från semestern? Det är iallafall jag och försöker få ordning på lite Godis-grammatiker. 
Och i samband med det har jag några nya ideer om GF-EBNF-syntax. Det är inte lika allvarligt som förut, 
inga förändringar utan bara utökningar.

1. Tabeller i högerledet:

	Noun ::= table{<_,Indef> => "barn"; <Sg,Def> => "barnet"; <Pl,Def> => "barnen"};
	==>
	fun a : Noun;
	lin a = {s=table{...}};

2. Parametrar i vänsterledet:

	Noun@{gen=Utr} ::= table{...};
	==>
	fun a : Noun;
	lin a : {s=table{...}} ** {gen=Utr};

Diskontinuerliga konstituenter fungerar som andra parametrar. Dvs, det finns alltid en huvudkonstituent, 
som definieras av högerledet. Alla andra konstituenter måste definieras som Cat@{s2="tjosan";...}

3. lincat-definitioner:

	lincat Noun@{gen:Gen} = Num*Spec => Str;
	lincat Det@{num:Num;spec:Spec} = Gen => Str;
	lincat NP@{num:Num};
	==>
	lincat Noun = {s:Num*Spec => Str} ** {gen:Gen};
	lincat Det = {s:Gen => Str} ** {num:Num;spec:Spec};
	lincat NP = {s:Str} ** {num:Num};

4. Tabellselektion i högerledet:

	VP ::= \\n => Verb!n NP;
	==>
	fun a : Verb -> NP -> VP;
	lin a x y = {s = \\n => x.s!n ++ y.s};

5. Parametrar i högerledet:

	NP ::= Det@{num=n;spec=d}!g Noun@{gen=g}!<n,d>;
	==>
	fun a : Det -> Noun -> NP;
	lin a x y = {s = x.s!y.gen ++ y.s!<x.num,x.spec>};

	(alltså: variabeln g i Noun@{gen=g} binds till y.gen (där y är variabeln som motsvarar Noun))

Alternativ variant med samma översättning:

	NP ::= Det@d!n.gen Noun@n!<d.num,d.spec>;

	(alltså: variabeln n i Noun@n binds till x)

Kombinera med vänsterledsparametrar:

	NP@{num=n} ::= Det@{num=n;spec=d}!g Noun@{gen=g}!<n,d>;
	==>
	lin a x y = {s = x.s!y.gen ++ y.s!<x.num,x.spec>} ** {num = x.num};

Alternativ variant med samma översättning:

	NP@{num=d.num} ::= Det@d!n.gen Noun@n!<d.num,d.spec>;


6. Semantik:

Eftersom en enda EBNF-regel ger upphov till flera GF-funktioner (som man inte känner till namnen på), så måste man ha ett 
sätt att specificera semantiken i EBNF. Mitt förslag är att syntaktiskt hantera semantiken på samma sätt som parametrar, fast 
med en egen operator (inte @ utan t.ex. /). Översättningen blir en egen konkret syntax för semantiken.

	NP / "ordinary_np" dsem nsem ::= Det/dsem@{num=n;spec=d}!g Noun/nsem@{gen=g}!<n,d>;
	NP / "interrogative" nsem ::= Which@{num=n}!g Noun/nsem@{gen=g}!<n,Indef>;
	==>
	fun a : Det -> Noun -> NP;
	fun b : Which -> Noun -> NP;
	lin a x y = {s = x.s!y.gen ++ y.s!<x.num,x.spec>};
	lin b x y = {s = x.s!y.gen ++ y.s!<x.num,Indef>};

	{-semantics-} lin a x y = {s = "ordinary_np" ++ x.s ++ y.s};
	{-semantics-} lin b x y = {s = "interrogative" ++ y.s};


7. Operatorer, resursgrammatiken:

Det jag INTE har fått att passa in än är hur man ska kunna använda sig av operatorer och resursgrammatiken. Eftersom 
konkatenering i EBNF är " " så kan inte funktionsapplikation vara " ". Mitt bästa förslag hittills är att funktionsapplikation är "", 
dvs att argumentet måste ligga dikt an mot funktionen. Det betyder att man måste innesluta argumentet i parenteser:

	lincat Nat = NP;
	Nat / "Succ" n ::= DetCN(DetSg(SgQuant(DefArt))(NoOrd))(ComplN2(regN2("successor"))(Nat/n));
	==>
	lincat Nat = {s : NP};
	fun a : Nat -> Nat;
	lin a x = {s = DetCN(DetSg(SgQuant(DefArt))(NoOrd))(ComplN2(regN2("successor"))(x.s));

Problemet är att det blir lätt att skriva fel (glömma sig och råka skriva ett mellanslag), men då får man åtminstone ett typfelmeddelande. 
Och sen kan man ju argumentera att ifall man gör så här avancerade saker så borde man ändå gå över till "riktig" GF...

Fast jag vill kunna använda enkla operatorer iallafall, t.ex:

	oper any2(a)(b)    = a b | b a;
	oper any3(a)(b)(c) = a any2(b)(c) | b any2(a)(c) | c any2(a)(b);
	==>
	oper any2(a)(b)    = variants{a++b ; b++a};
	oper any3(a)(b)(c) = variants{a++any2(b)(c) ; b++any2(a)(c) ; c++any2(a)(b)};

	ShortAnswer / "event" e "date" d "time" t ::= any3(Event/e)(Date/d)(Time/t);
	==>
	fun a : Event -> Date -> Time -> ShortAnswer;
	lin a x y z = {s = any3(x.s)(y.s)(z.s)};
	{-semantics-} lin a x y z = {s = "event" ++ x.s ++ "date" ++ y.s ++ "time" ++ t.s};


8. EBNF-operatorerna ? * + funkar som förut för strängar (och tabeller). Om man har extra parametrar så får man väl kopiera ideerna från GF-listor.

Reply on Aarne's reply:

	Från: 	peb@ling.gu.se
	Ämne: 	Re: Lite ny GF-syntax...
	Datum: 	må 20 aug 2007 11.32.09 GMT+02:00
	Till: 	aarne@cs.chalmers.se
	Kopia: 	bringert@cs.chalmers.se


20 aug 2007 kl. 09.40 skrev Aarne Ranta:

> Tack för det utarbetade förslaget! Det borde vara lätt att implementera detta för att experimentera med: 
> bara skriva en BNFC-grammatik och en genereringsfunktion till GF-syntax.

Jag gör nog det så småningom.

> > 2. Parametrar i vänsterledet:
> > 
> > 	Noun@{gen=Utr} ::= table{...};
> > 	==>
> > 	fun a : Noun;
> > 	lin a : {s=table{...}} ** {gen=Utr};
> 
> Det är en bra insikt att parametriska drag hamnar i högerledet och inherenta i vänsterledet. Namnet 'a' automatgenereras?

Ja, precis som i den nuvarande EBNF-konverteringen.

> På vilken nivå får man slänga in EBNF-operatorer? Innanför tabeller också?

Ja, det är tanken. A* och A+ kan översättas till ListA (två olika varianter), och A? till MaybeA:

A*  ==>  cat [A]{0};
A+  ==>  cat [A]{1};
A?  ==>  cat MaybeA; fun NothingA : MaybeA; fun JustA : A -> MaybeA;

> Var definieras parametertyperna?

De får man definiera själv:

param Num = Sg | Pl;

> Görs typkontroll först på den genererade koden? Eller finns det ett typsystem på EBNF-nivån?

Det blir väl på den genererade koden. Jag har iallafall inte tänkt på något annat.

> > Diskontinuerliga konstituenter fungerar som andra parametrar. Dvs, det finns alltid en huvudkonstituent, 
> > som definieras av högerledet. Alla andra konstituenter måste definieras som Cat@{s2="tjosan";...}
> 
> Så hur blir det om diskontinuiteten är innanför en tabell:
> 
>  lincat VP = {s : VForm => {fin,inf : Str}}

Det har jag inte funderat över. Kanske det inte ska tillåtas. Kanske det ger sig av sig själv, isåfall ungefär så här:

	lincat VP = VForm => {fin,inf:Str};
	VP ::= \\x => {fin=...; inf=...};

> > 5. Parametrar i högerledet:
> > 
> > 	NP ::= Det@{num=n;spec=d}!g Noun@{gen=g}!<n,d>;
> > 	==>
> > 	fun a : Det -> Noun -> NP;
> > 	lin a x y = {s = x.s!y.gen ++ y.s!<x.num,x.spec>};
> > 
> > 	(alltså: variabeln g i Noun@{gen=g} binds till y.gen (där y är variabeln som motsvarar Noun))
> 
> Blir lite omständigt att man måste skapa en ny variabel g, och svårt att se var den binds och till vad. 
> Det är nog Noun@{gen=g} som binder, men ovanligt att ett högerled av en ekvation binder en variabel.

Variablerna n,d,g kan ses som logiska variabler som unifieras. Dock med restriktionen att de måste 
förekomma exakt en gång i en @-bindning i högerledet.

> > Alternativ variant med samma översättning:
> > 
> > 	NP ::= Det@d!n.gen Noun@n!<d.num,d.spec>;
> > 
> > 	(alltså: variabeln n i Noun@n binds till x)
> 
> Vilket x? Hur ser man detta?

Sorry, det x som introducerades i exemplet innan - dvs x är variabeln som motsvarar Det.

> > 6. Semantik:
> > 
> > Eftersom en enda EBNF-regel ger upphov till flera GF-funktioner (som man inte känner till namnen på), så måste man ha 
> > ett sätt att specificera semantiken i EBNF. Mitt förslag är att syntaktiskt hantera semantiken på samma sätt som parametrar, 
> > fast med en egen operator (inte @ utan t.ex. /). Översättningen blir en egen konkret syntax för semantiken.
> > 
> > 	NP / "ordinary_np" dsem nsem ::= Det/dsem@{num=n;spec=d}!g Noun/nsem@{gen=g}!<n,d>;
> > 	NP / "interrogative" nsem ::= Which@{num=n}!g Noun/nsem@{gen=g}!<n,Indef>;
> > 	==>
> > 	fun a : Det -> Noun -> NP;
> > 	fun b : Which -> Noun -> NP;
> > 	lin a x y = {s = x.s!y.gen ++ y.s!<x.num,x.spec>};
> > 	lin b x y = {s = x.s!y.gen ++ y.s!<x.num,Indef>};
> > 
> > 	{-semantics-} lin a x y = {s = "ordinary_np" ++ x.s ++ y.s};
> > 	{-semantics-} lin b x y = {s = "interrogative" ++ y.s};
> 
> Finns det ett generellt sätt att ha två konkreta syntaxer av en abstrakt?
> Då skulle man verkligen behöva hänvisa till konstruerarna i abstrak syntax.

Jag har tyvärr inte kommit på något generellt sätt. Om de två konkreta syntaxerna har samma lineariseringstyper 
(eller använder sig av resursgrammatiker) så går det bra (och blir snyggt och enkelt).

Min lösning är just att använda en konkret semantik-syntax som kan vara gemensam för olika språk. 
Dvs det blir inte abstrakta syntaxen som blir interlingua, utan semantiken som är en konkret syntax.

Problemet med den abstrakta syntaxen är att en EBNF-regel kommer att expanderas till flera GF-regler, 
och då kan man ju inte hänvisa till den abstrakta syntaxen eftersom man inte vet vilken den är...

> > 7. Operatorer, resursgrammatiken:
> > 
> > Det jag INTE har fått att passa in än är hur man ska kunna använda sig av operatorer och resursgrammatiken. 
> > Eftersom konkatenering i EBNF är " " så kan inte funktionsapplikation vara " ". Mitt bästa förslag hittills är att 
> > funktionsapplikation är "", dvs att argumentet måste ligga dikt an mot funktionen. 
> > Det betyder att man måste innesluta argumentet i parenteser:
> > 
> > 	lincat Nat = NP;
> > 	Nat / "Succ" n ::= DetCN(DetSg(SgQuant(DefArt))(NoOrd))(ComplN2(regN2("successor"))(Nat/n));
> > 	==>
> > 	lincat Nat = {s : NP};
> > 	fun a : Nat -> Nat;
> > 	lin a x = {s = DetCN(DetSg(SgQuant(DefArt))(NoOrd))(ComplN2(regN2("successor"))(x.s));
> > 
> > Problemet är att det blir lätt att skriva fel (glömma sig och råka skriva ett mellanslag), men då får man åtminstone ett typfelmeddelande. 
> > Och sen kan man ju argumentera att ifall man gör så här avancerade saker så borde man ändå gå över till "riktig" GF...
> 
> Det är aldrig bra att förbjuda mellanslag mellan tokens. Och krågnligt om man får ett mystiskt typfel långt senare i kompileringen.

Visst, jag håller med. Men jag har helt enkelt inte kommit på något bättre...

> > Vad tycks? Fördelen (som jag ser det) är att
> > 
> > * Det blir ingen förändring av GF-syntaxen
> > * Den gamla EBNF-syntaxen gäller fortfarande
> 
> Det håller jag med om. Bara man avstår från den där icke-mellanslag syntaxen så är det lätt att implementera detta med BNFC.
> 
> Men jag ser nackdelar också, den största är att man inte kan ha flerspråkiga grammatiker.

japp

> Det finns heller ingen modularitet, annat än den primitiva "include"-mekanismen.

Det finns inget som hindrar att man återanvänder GF:s modulsyntax även här.

> Och sedan frågan om semantik: finns det något naturligt fragment av GF, med en oberoende semantik, till vilken 
> formalismen motsvarar och mot vilken den skulle kunna typkontrolleras. I annat fall påminner den mycket om 
> "metagrammatik", sådan som Yannick Parmentier jobbar med.

Bra fråga. Jag har inte alls funderat över det.

> Jag håller förresten på att som sakkunnig läsa Joseph le Roux avhandling om samma tema, se
> 
>  http://www.loria.fr/~leroux/
> 
> Det finns gemensamma drag i deras approach och din, även den att de tänker i termer av logikprogrammering. En fråga som man 
> kan ställa är om möjligen den här EBNF-baserade notationen skulle vara lättare att översätta till unifieringsbaserade format än GF är.

Jo, det är den nog.

Note: See TracTickets for help on using tickets.