fix(reader): prevent false phrasal verb detection for noun collocations and improve literary translation accuracy
This commit is contained in:
+42
-25
@@ -46,7 +46,14 @@ IRREGULARS = {
|
||||
|
||||
PRONOUNS_AND_OBJECTS = {
|
||||
"it", "him", "her", "them", "us", "me", "you", "this", "that", "these", "those",
|
||||
"things", "something", "everything", "anything", "all", "back", "away"
|
||||
"things", "something", "everything", "anything", "all"
|
||||
}
|
||||
|
||||
PHRASAL_PARTICLES = {
|
||||
"about", "across", "ahead", "along", "apart", "around", "round", "aside",
|
||||
"at", "away", "back", "by", "down", "for", "forth", "forward", "in",
|
||||
"into", "off", "on", "onto", "out", "over", "past", "round", "through",
|
||||
"to", "together", "under", "up", "upon", "with"
|
||||
}
|
||||
|
||||
# Curated high-frequency English phrasal verbs (CEFR A2-B2) with clean translations
|
||||
@@ -326,20 +333,26 @@ def detect_phrasal_verb(
|
||||
}
|
||||
break
|
||||
|
||||
# Check offline dictionary
|
||||
row = execute_query(
|
||||
"SELECT term, translation FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||||
(cand,),
|
||||
)
|
||||
if row:
|
||||
match_result = {
|
||||
"term": row[0],
|
||||
"raw": raw_match,
|
||||
"translation": row[1],
|
||||
"separable": False,
|
||||
"matched_words": tokens[start : start + span_len],
|
||||
}
|
||||
break
|
||||
# Check offline dictionary only for genuine phrasal verbs:
|
||||
# 1. Candidate must end with a known particle (e.g. 'turn on', 'come up with')
|
||||
# 2. pos in offline_dictionary must explicitly be a verb / verb phrase
|
||||
cand_words = cand.split()
|
||||
if len(cand_words) >= 2 and cand_words[-1] in PHRASAL_PARTICLES:
|
||||
row = execute_query(
|
||||
"SELECT term, translation, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||||
(cand,),
|
||||
)
|
||||
if row:
|
||||
pos_val = (row[2] or "").lower()
|
||||
if "verb" in pos_val:
|
||||
match_result = {
|
||||
"term": row[0],
|
||||
"raw": raw_match,
|
||||
"translation": row[1],
|
||||
"separable": False,
|
||||
"matched_words": tokens[start : start + span_len],
|
||||
}
|
||||
break
|
||||
if match_result:
|
||||
break
|
||||
if match_result:
|
||||
@@ -352,8 +365,10 @@ def detect_phrasal_verb(
|
||||
if lower_tokens[v_idx + 1] in PRONOUNS_AND_OBJECTS:
|
||||
p_idx = v_idx + 2
|
||||
if idx in (v_idx, p_idx):
|
||||
v_lemmas = lemmatize_word(lower_tokens[v_idx])
|
||||
particle = lower_tokens[p_idx]
|
||||
if particle not in PHRASAL_PARTICLES:
|
||||
continue
|
||||
v_lemmas = lemmatize_word(lower_tokens[v_idx])
|
||||
raw_match = " ".join(tokens[v_idx : p_idx + 1])
|
||||
for v in v_lemmas:
|
||||
cand = f"{v} {particle}"
|
||||
@@ -367,18 +382,20 @@ def detect_phrasal_verb(
|
||||
}
|
||||
break
|
||||
row = execute_query(
|
||||
"SELECT term, translation FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||||
"SELECT term, translation, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
|
||||
(cand,),
|
||||
)
|
||||
if row:
|
||||
match_result = {
|
||||
"term": row[0],
|
||||
"raw": raw_match,
|
||||
"translation": row[1],
|
||||
"separable": True,
|
||||
"matched_words": [tokens[v_idx], tokens[p_idx]],
|
||||
}
|
||||
break
|
||||
pos_val = (row[2] or "").lower()
|
||||
if "verb" in pos_val:
|
||||
match_result = {
|
||||
"term": row[0],
|
||||
"raw": raw_match,
|
||||
"translation": row[1],
|
||||
"separable": True,
|
||||
"matched_words": [tokens[v_idx], tokens[p_idx]],
|
||||
}
|
||||
break
|
||||
if match_result:
|
||||
break
|
||||
if match_result:
|
||||
|
||||
Reference in New Issue
Block a user