Skip to content

Commit add11a8

Browse files
Merge pull request #68 from mideind/fix/parse-coverage
Fix seven parse coverage gaps; add error rule for non-agreeing postposed adjectives
2 parents cd7d97e + 32d3be2 commit add11a8

4 files changed

Lines changed: 249 additions & 3 deletions

File tree

src/reynir/Greynir.grammar

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ SetningÁnF_et_p3_hk →
16621662

16631663
EinSetningÁnF/tala/pers/kyn →
16641664
Atviksliður? ÖfugurSagnliður/tala/pers/kyn
1665-
LoTengtSögn_nf/tala/kyn? ÖfugtFramhald/tala/pers/kyn*
1665+
LoTengtSögn_nf/tala/kyn? SamanburðurNl? ÖfugtFramhald/tala/pers/kyn*
16661666
# Lýsingarorð á undan sögn:
16671667
# (Ráðherrar taka þær ákvarðanir sem) nauðsynlegar eru/þykja/teljast til rækslu starfa þeirra
16681668
| LoTengtSögn_nf/tala/kyn Sögn_0/tala/pers/kyn SagnInnskotAtv?
@@ -2796,6 +2796,12 @@ SagnarBotn →
27962796
| Nl_ef AtvFs? so_subj_nh_ef
27972797
# (Anna telur) fólki fækka í landinu
27982798
| Nl_þgf AtvFs? so_subj_nh_þgf
2799+
# (Hún segir) mig hafa dreymt (vel)
2800+
| Nl/aukafall AtvFs? 'hafa:so'_0_nh so_subj_sagnb/aukafall ÓpSagnarBotn?
2801+
# (Hún segir) Spáni hafa mistekist (að vernda landamærin)
2802+
# (miðmyndarsögn með frumlagi í þágufalli, sbr. finítu regluna
2803+
# 'NlFrumlag_þgf ... HjSögnMM so_mm_sagnb MiðmyndarBotn?')
2804+
| Nl_þgf AtvFs? 'hafa:so'_0_nh so_mm_sagnb MiðmyndarBotn?
27992805
# (Már segir) [í grundvallaratriðum] gæta misskilnings (hjá Hannesi)
28002806
| FsAtv? so_subj_nh_ef Nl_ef
28012807
# !!! Ekki virðist þörf fyrir öfuga orðaröð í þgf eða þf
@@ -3743,8 +3749,17 @@ Fyrirbæri_ft/fall/kyn →
37433749

37443750
Númer →
37453751
'númer:hk' Tala_hk_nf
3752+
| NúmerTala
3753+
3754+
# Óbeygð tala í hvorugkyni nefnifalls sem auðkenni á eftir nafnorði:
3755+
# '(lögreglu)stöð tvö', 'stofa fimm', 'hlið átta', 'rás eitt'
3756+
NúmerTala →
3757+
Töluorð_et_nf_hk
3758+
| Töluorð_ft_nf_hk
37463759

37473760
$score(+8) Númer
3761+
# Velja frekar sambeygða tölu (Fjöldi) en auðkennistölu, ef báðar koma til greina
3762+
$score(-4) NúmerTala
37483763

37493764
Fjöldi_ft/fall/kyn → to_ft/fall/kyn | töl_ft/fall/kyn
37503765

@@ -3893,6 +3908,7 @@ NlStak_p3/tala/fall/kyn →
38933908
NlKjarni/tala/fall/kyn NlStakTagl/tala/fall/kyn?
38943909
| NlFornafn/tala/fall/kyn
38953910
| Pfn/kyn/tala/fall to/tala/fall/kyn? 'persónulega:ao'? # 'þið tvær', 'hann einn', 'hán eitt'
3911+
| Pfn/kyn/tala/fall LoEftirNl/tala/fall/kyn # '(með) hann fremstan (í fararbroddi)', '(ég hitti) hana glaða'
38963912
| LoTöluorð_ef 'konar:kk'_ef_et NlKjarni/tala/fall/kyn # 'tvenns/þrenns/ferns konar innstungur'
38973913
| Raðnr/fall/kyn NlKjarni/tala/fall/kyn Fornafn/tala/fall/kyn* # 1. verðlaunin öll, 1.-3. sætið, 10. og 12. árið
38983914
| NlStakNema/tala/fall/kyn
@@ -5954,6 +5970,7 @@ FsMeðFallstjórn →
59545970
# Fleiryrtar forsetningar sem eru ekki dregnar saman í Phrases.conf
59555971
| 'nær:fs'_þgf 'draga:so'_op_gm_et_p3 Nl_þgf # 'þegar nær dró/dregur jólum'
59565972
| 'beggja:fn'_hk_ef_ft 'vegna:fs'_ef Nl_ef # 'beggja vegna vegarins'
5973+
| FsVegnaEftirNl # 'sýningarinnar vegna', 'mín vegna'
59575974
| 'bera:so'_lhþt_sb_hk_nf_et "saman:ao" 'við:fs'_þf Nl_þf # borið saman við (fyrra ár)
59585975
| "fyrir:ao" "nú:ao"? 'utan:fs'_þf Nl_þf
59595976
| "innan:ao" "sem:st" 'utan:fs'_ef Nl_ef
@@ -5993,6 +6010,14 @@ FsMeðFallstjórn →
59936010

59946011
$score(+1) FsMeðFallstjórn
59956012

6013+
# Eignarfallsliður á undan 'vegna': 'sýningarinnar vegna',
6014+
# 'veðursins vegna', 'mín vegna'
6015+
FsVegnaEftirNl →
6016+
Nl_ef 'vegna:fs'_ef
6017+
6018+
# Þarf að vinna gegn rangri greiningu á 'vegna' sem lýsingarorði
6019+
$score(+4) FsVegnaEftirNl
6020+
59966021
MiðaðVið →
59976022
"miðað:so" 'við:fs'_þf
59986023
| 'miðað_við:fs'_þf # Samtals eigið fé m.v. síðustu tölur ...
@@ -7671,6 +7696,30 @@ VillaEndingIR →
76717696
$tag(error) VillaEndingIR
76727697
$score(-999) VillaEndingIR
76737698

7699+
# Regla fyrir villu þar sem lýsingarorð (oft lýsingarháttur þátíðar)
7700+
# með fallstýrðu andlagi stendur á eftir nafnlið en sambeygist honum
7701+
# ekki í falli, t.d. 'móðurfélag fleiri félaga tengdum rekstri
7702+
# Morgunblaðsins' (rétt: 'tengdra'); villan stafar oft af aðlöðun
7703+
# að falli andlagsins ('félögum tengdum rekstri')
7704+
7705+
LoEftirNl/tala/fall/kyn →
7706+
> VillaLoEftirNlMeðAndlagi/fall/tala/kyn
7707+
7708+
VillaLoEftirNlMeðAndlagi_nf/tala/kyn →
7709+
LoEftirNlMeðAndlagi/fallxnf/tala/kyn
7710+
7711+
VillaLoEftirNlMeðAndlagi_þf/tala/kyn →
7712+
LoEftirNlMeðAndlagi/fallxþf/tala/kyn
7713+
7714+
VillaLoEftirNlMeðAndlagi_þgf/tala/kyn →
7715+
LoEftirNlMeðAndlagi/fallxþgf/tala/kyn
7716+
7717+
VillaLoEftirNlMeðAndlagi_ef/tala/kyn →
7718+
LoEftirNlMeðAndlagi/fallxef/tala/kyn
7719+
7720+
$tag(error) VillaLoEftirNlMeðAndlagi/fall/tala/kyn
7721+
$score(-999) VillaLoEftirNlMeðAndlagi/fall/tala/kyn
7722+
76747723
# Orð sem endar á -ana í þolfalli notað í stað eignarfalls:
76757724
# 'niðurstaða þingflokkana', 'hattar karlana'
76767725

src/reynir/bintokenizer.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,6 +1259,24 @@ def _compatible(pn: PersonNameTuple, npn: PersonNameTuple) -> bool:
12591259
return True
12601260

12611261

1262+
def _add_uninflected_genitive(gn: List[PersonNameTuple]) -> List[PersonNameTuple]:
1263+
"""If a name appears in the same form in the nominative, accusative
1264+
and dative cases, it is a non-inflecting (foreign) name. Such names
1265+
are also used unmodified in genitive position ('Samtök Paul Watson',
1266+
'bók Mary Robinson'), so we add the genitive case to the list of
1267+
possible interpretations."""
1268+
seen: Dict[Tuple[str, Optional[str]], Set[str]] = defaultdict(set)
1269+
for pn in gn:
1270+
if pn.case:
1271+
seen[(pn.name, pn.gender)].add(pn.case)
1272+
additions = [
1273+
PersonNameTuple(name=name, gender=gender, case="ef")
1274+
for (name, gender), cases in seen.items()
1275+
if "ef" not in cases and cases >= {"nf", "þf", "þgf"}
1276+
]
1277+
return gn + additions if additions else gn
1278+
1279+
12621280
def parse_phrases_2(
12631281
token_stream: TokenIterator, token_ctor: TokenConstructor, auto_uppercase: bool
12641282
) -> TokenIterator:
@@ -1604,7 +1622,7 @@ def eat_surnames(
16041622
if not weak:
16051623
# Return a person token with the accumulated name
16061624
# and the intersected set of possible cases
1607-
token = token_ctor.Person(w, gn)
1625+
token = token_ctor.Person(w, _add_uninflected_genitive(gn))
16081626
token.original = namespan
16091627

16101628
# Yield the current token and advance to the lookahead

src/reynir/config/Phrases.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1573,7 +1573,7 @@ meaning = fs frasi -
15731573
"láta* slag standa" so kk so
15741574
"láta* þess getið" so pfn so
15751575
"vísa* málinu" so hk
1576-
"vera* bent á" so so ao
1576+
"vera* bent á" so so fs/ao
15771577
"um síðustu áramót" fs lo hk
15781578
"um síðustu mánaðamót" fs lo hk
15791579
"um sig" fs *

test/test_parse.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,178 @@ def test_aukafall(r):
22452245
assert s and s.tree
22462246

22472247

2248+
def test_impersonal_passive_prep(r):
2249+
"""The 'vera* bent á' ambiguous phrase must retain the preposition
2250+
meaning of 'á', so that 'er bent á' + Nl parses"""
2251+
s = r.parse_single("Í skýrslunni er bent á kostina.")
2252+
assert s and s.tree
2253+
assert (
2254+
s.tree.flat_with_all_variants
2255+
== "S0 S-MAIN IP PP P fs_þgf /P NP no_et_gr_kvk_þgf /NP /PP "
2256+
"VP VP-AUX so_et_fh_gm_nt_p3 /VP-AUX VP so_gm_sagnb /VP "
2257+
"PP P fs_þf /P NP no_ft_gr_kk_þf /NP /PP /VP /IP /S-MAIN p /S0"
2258+
)
2259+
s = r.parse_single("Í skýrslunni er bent á kosti og galla upptöku evru.")
2260+
assert s and s.tree
2261+
# 'bent á' followed by a subordinate clause must still work
2262+
s = r.parse_single("Í skýrslunni er bent á að vandinn sé mikill.")
2263+
assert s and s.tree
2264+
s = r.parse_single(
2265+
"Í nýrri ársskýrslu sjóðsins um Ísland er bent á kosti og galla "
2266+
"upptöku evru og varað við því að verðtrygging í íslensku "
2267+
"efnahagslífi geti viðhaldið verðbólgu."
2268+
)
2269+
assert s and s.tree
2270+
2271+
2272+
def test_uninflected_genitive_names(r):
2273+
"""Non-inflecting (foreign) person names, i.e. names having identical
2274+
forms in nf/þf/þgf, should also be accepted in genitive contexts"""
2275+
s = r.parse_single("Samtök Paul Watson mótmæltu hvalveiðum.")
2276+
assert s and s.tree
2277+
assert (
2278+
s.tree.flat_with_all_variants
2279+
== "S0 S-MAIN IP NP-SUBJ no_ft_hk_nf NP-POSS person_ef_kk person_ef_kk "
2280+
"/NP-POSS /NP-SUBJ VP VP so_1_þgf_fh_ft_gm_p3_þt /VP "
2281+
"NP-OBJ no_ft_kvk_þgf /NP-OBJ /VP /IP /S-MAIN p /S0"
2282+
)
2283+
s = r.parse_single("Ég las bók John Lennon.")
2284+
assert s and s.tree
2285+
s = r.parse_single(
2286+
"Samtök Paul Watson leiða líkur að því að þau hafi með aðgerðum "
2287+
"sínum frá því að hvalveiðitímabilið hófst bjargað lífi "
2288+
"allt að þrjátíu langreyða."
2289+
)
2290+
assert s and s.tree
2291+
# Inflecting Icelandic names must not gain a genitive interpretation
2292+
s = r.parse_single("Samtök Guðmundur Jónsson eru góð.")
2293+
assert s.tree is None
2294+
# Token-level check of person name cases
2295+
from reynir.bintokenizer import tokenize
2296+
2297+
toks = [t for t in tokenize("Samtök Paul Watson mótmæltu hvalveiðum.")]
2298+
pw = next(t for t in toks if t.txt == "Paul Watson")
2299+
assert set(pn.case for pn in pw.person_names) == {"nf", "þf", "þgf", "ef"}
2300+
toks = [t for t in tokenize("Þarna gengur Jón.")]
2301+
jon = next(t for t in toks if t.txt == "Jón")
2302+
assert "ef" not in set(pn.case for pn in jon.person_names)
2303+
2304+
2305+
def test_sem_role_relative_clause(r):
2306+
"""A 'sem' + Nl_nf role complement ('starfar sem sérfræðingur')
2307+
must be allowed inside a subject-gap relative clause"""
2308+
s = r.parse_single("Konan, sem starfar sem sérfræðingur hjá bankanum, er glöð.")
2309+
assert s and s.tree
2310+
assert (
2311+
s.tree.flat_with_all_variants
2312+
== "S0 S-MAIN IP NP-SUBJ no_et_gr_kvk_nf p CP-REL C stt /C "
2313+
"IP VP so_0_et_fh_gm_nt_p3 /VP CP-ADV-CMP C st /C NP no_et_kk_nf "
2314+
"PP P fs_þgf /P NP no_et_gr_kk_þgf /NP /PP /NP /CP-ADV-CMP /IP "
2315+
"/CP-REL p /NP-SUBJ VP VP-AUX so_et_fh_gm_nt_p3 /VP-AUX "
2316+
"NP-PRD lo_et_kvk_nf_sb /NP-PRD /VP /IP /S-MAIN p /S0"
2317+
)
2318+
s = r.parse_single(
2319+
"Doktor Stefán Ólafsson, sem starfar sem sérfræðingur hjá Eflingu, "
2320+
"gefur ekki mikið fyrir myljandi hagnað bankanna."
2321+
)
2322+
assert s and s.tree
2323+
2324+
2325+
def test_oblique_subject_infinitive(r):
2326+
"""Oblique subject + perfect infinitive ('hafa' + supine) in the
2327+
complement of segja/telja: 'segir Spáni hafa mistekist'"""
2328+
s = r.parse_single("Hún segir Spáni hafa mistekist að vernda landamærin.")
2329+
assert s and s.tree
2330+
assert (
2331+
s.tree.flat_with_all_variants
2332+
== "S0 S-MAIN IP NP-SUBJ pfn_et_kvk_nf_p3 /NP-SUBJ VP VP "
2333+
"so_1_þf_et_fh_gm_nt_p3 /VP IP NP no_et_kk_þgf /NP VP so_0_gm_nh /VP "
2334+
"VP so_mm_sagnb /VP IP-INF TO nhm /TO VP VP so_1_þf_gm_nh /VP "
2335+
"NP-OBJ no_ft_gr_hk_þf /NP-OBJ /VP /IP-INF /IP /VP /IP /S-MAIN p /S0"
2336+
)
2337+
s = r.parse_single("Hún segir mig hafa dreymt vel.")
2338+
assert s and s.tree
2339+
s = r.parse_single("Hún telur Spáni hafa mistekist.")
2340+
assert s and s.tree
2341+
s = r.parse_single(
2342+
"Hún segir Spáni hafa mistekist að vernda ytri landamæri "
2343+
"Schengen-svæðisins gegn innrás."
2344+
)
2345+
assert s and s.tree
2346+
2347+
2348+
def test_postposed_vegna(r):
2349+
"""A genitive Nl preceding 'vegna' ('sýningarinnar vegna')
2350+
should parse as a prepositional phrase"""
2351+
s = r.parse_single("Sýningarinnar vegna ákvað hann þetta.")
2352+
assert s and s.tree
2353+
assert (
2354+
s.tree.flat_with_all_variants
2355+
== "S0 S-MAIN IP PP NP no_ef_et_gr_kvk /NP P fs_ef /P /PP "
2356+
"VP VP so_1_þf_et_fh_gm_p3_þt /VP NP-SUBJ pfn_et_kk_nf_p3 /NP-SUBJ "
2357+
"NP-OBJ fn_et_hk_þf /NP-OBJ /VP /IP /S-MAIN p /S0"
2358+
)
2359+
s = r.parse_single("Hann gerði þetta mín vegna.")
2360+
assert s and s.tree
2361+
s = r.parse_single("Hann gerði þetta veðursins vegna.")
2362+
assert s and s.tree
2363+
# Normal (preposed) order must be unaffected
2364+
s = r.parse_single("Hann gerði þetta vegna veðursins.")
2365+
assert s and s.tree
2366+
s = r.parse_single("Trén standa beggja vegna vegarins.")
2367+
assert s and s.tree
2368+
s = r.parse_single(
2369+
"Umboðsmaður Boy George sagði að sýningarinnar vegna hefði hann "
2370+
"ákveðið að söngvarinn yrði ekki með í henni."
2371+
)
2372+
assert s and s.tree
2373+
2374+
2375+
def test_pronoun_postposed_adjective(r):
2376+
"""A personal pronoun followed by an agreeing adjective phrase
2377+
should form a noun phrase: '(með) hann fremstan (í fararbroddi)'"""
2378+
s = r.parse_single("Með hann fremstan í fararbroddi vann liðið leikinn.")
2379+
assert s and s.tree
2380+
assert (
2381+
s.tree.flat_with_all_variants
2382+
== "S0 S-MAIN IP PP P fs_þf /P NP pfn_et_kk_p3_þf lo_esb_et_kk_þf "
2383+
"PP P fs_þgf /P NP no_et_kk_þgf /NP /PP /NP /PP "
2384+
"VP VP so_1_þf_et_fh_gm_p3_þt /VP NP-SUBJ no_et_gr_hk_nf /NP-SUBJ "
2385+
"NP-OBJ no_et_gr_kk_þf /NP-OBJ /VP /IP /S-MAIN p /S0"
2386+
)
2387+
s = r.parse_single("Ég hitti hana glaða.")
2388+
assert s and s.tree
2389+
s = r.parse_single(
2390+
"Með hann fremstan í fararbroddi tókst liði Levante "
2391+
"að bjarga sér frá falli."
2392+
)
2393+
assert s and s.tree
2394+
2395+
2396+
def test_designation_numeral(r) -> None:
2397+
"""An uninflected neuter nominative numeral used as a designation
2398+
after a noun: '(lögreglu)stöð tvö', 'stofa fimm'"""
2399+
s = r.parse_single("Hann býr í umdæmi lögreglustöðvar tvö.")
2400+
assert s and s.tree
2401+
assert (
2402+
s.tree.flat_with_all_variants
2403+
== "S0 S-MAIN IP NP-SUBJ pfn_et_kk_nf_p3 /NP-SUBJ VP VP so_0_et_fh_gm_nt_p3 /VP "
2404+
"PP P fs_þgf /P NP no_et_hk_þgf NP-POSS no_ef_et_kvk to_ft_hk_nf "
2405+
"/NP-POSS /NP /PP /VP /IP /S-MAIN p /S0"
2406+
)
2407+
s = r.parse_single("Hann býr í stofu fimm.")
2408+
assert s and s.tree
2409+
s = r.parse_single(
2410+
"Það átti sér stað í umdæmi lögreglustöðvar tvö, "
2411+
"sem sér um Hafnarfjörð og Garðabæ."
2412+
)
2413+
assert s and s.tree
2414+
# An agreeing numeral must still be preferred where possible
2415+
s = r.parse_single("Ég sá mennina þrjá.")
2416+
assert s and s.tree
2417+
assert "to_ft_kk_þf" in s.tree.flat_with_all_variants
2418+
2419+
22482420
if __name__ == "__main__":
22492421
# When invoked as a main module, do a verbose test
22502422
from reynir import Greynir
@@ -2296,4 +2468,11 @@ def test_aukafall(r):
22962468
print(e)
22972469
test_foreign(g)
22982470
test_aukafall(g)
2471+
test_impersonal_passive_prep(g)
2472+
test_uninflected_genitive_names(g)
2473+
test_sem_role_relative_clause(g)
2474+
test_oblique_subject_infinitive(g)
2475+
test_postposed_vegna(g)
2476+
test_pronoun_postposed_adjective(g)
2477+
test_designation_numeral(g)
22992478
g.__class__.cleanup()

0 commit comments

Comments
 (0)