-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
132 lines (114 loc) · 3.24 KB
/
Copy pathmain.py
File metadata and controls
132 lines (114 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
import spacy
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="语法树解析 API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
nlp = spacy.load("en_core_web_sm")
class SentenceRequest(BaseModel):
text: str
class SyntaxTreeNode(BaseModel):
id: str = ""
text: str
pos: str
dep: str
dep_zh: str = ""
clause_label: str = ""
idx: int = 0
subtree_ids: List[str] = []
children: List["SyntaxTreeNode"] = []
DEP_ZH = {
"ROOT": "核心",
"nsubj": "主语",
"nsubjpass": "被动主语",
"dobj": "宾语",
"dative": "间接宾语",
"iobj": "间接宾语",
"pobj": "介词宾语",
"attr": "表语",
"prep": "介词结构",
"det": "限定词",
"amod": "形容词修饰",
"advmod": "副词修饰",
"relcl": "定语从句",
"acl": "定语从句",
"advcl": "状语从句",
"ccomp": "宾语从句",
"xcomp": "补语从句",
"parataxis": "并列从句",
"aux": "助动词",
"auxpass": "被动助动词",
"neg": "否定词",
"cc": "连词",
"conj": "并列成分",
"mark": "从句标记",
"case": "格标记",
"nummod": "数量修饰",
"appos": "同位语",
"poss": "所有格",
"punct": "标点",
"compound": "复合词",
"acomp": "形容词补语",
"prt": "小品词",
"expl": "存在词",
"cop": "系词",
"npadvmod": "名词性副词修饰",
"agent": "施动者",
"predet": "前位限定词",
"quantmod": "量词修饰",
"tmod": "时间修饰",
"intj": "感叹词",
"csubj": "主语从句",
"csubjpass": "被动主语从句",
"advcl:if": "条件状语从句",
"advcl:when": "时间状语从句",
"advcl:because": "原因状语从句",
"relcl:subj": "定语从句",
"relcl:obj": "定语从句",
}
CLAUSE_DEPS = {"relcl", "acl", "advcl", "ccomp", "xcomp", "parataxis", "csubj", "csubjpass"}
def build_tree(token, path="0") -> dict:
dep = token.dep_
clause_label = DEP_ZH.get(dep, "") if dep in CLAUSE_DEPS else ""
children_list = [
build_tree(child, f"{path}.{i}")
for i, child in enumerate(token.children)
]
subtree_ids = [path]
for child in children_list:
subtree_ids.extend(child["subtree_ids"])
return {
"id": path,
"text": token.text,
"pos": token.pos_,
"dep": dep,
"dep_zh": DEP_ZH.get(dep, dep),
"clause_label": clause_label,
"idx": token.i,
"subtree_ids": subtree_ids,
"children": children_list,
}
@app.post("/analyze", response_model=SyntaxTreeNode)
async def analyze_syntax(request: SentenceRequest):
doc = nlp(request.text)
root_token = next((token for token in doc if token.dep_ == "ROOT"), None)
if not root_token:
return {
"id": "0",
"text": "Error",
"pos": "NONE",
"dep": "NONE",
"dep_zh": "NONE",
"clause_label": "",
"idx": 0,
"subtree_ids": ["0"],
"children": [],
}
return build_tree(root_token)