يقوم هذا المستودع ببناء غلاف بايثون رفيع حول OpenCCG باستخدام مساحة GUM، وهو جاهز للتشغيل داخل حاوية عامل إرساء. يمكنك العثور على نسخة حية على litmus.informatik.uni-bremen.de/openccg.
بعد docker-compose up
أولي، يمكن الاستعلام عن الخدمة باستخدام طلب POST بسيط، على سبيل المثال باستخدام حليقة:
$ curl --data "Take the cup." "localhost/openccg/parse?graphs"
{"version": "2.2.0", "application": "web-openccg", "uuid": "3bafdaf8-cc9c-4fdf-b455-c9687babba49", "sentence": "take the cup", "parses": ..., "http_status": 200, "json_parses": ..., "graphs": ...}
يتم تضمين حقل "الرسوم البيانية" فقط في حالة وجود معلمة عنوان URL graphs
.
على سبيل المثال، باستخدام طلبات بايثون:
import requests
# Without graphs
print ( requests . post ( 'http://localhost/openccg/parse' , data = { 'sentence' : 'Take the cup.' }). json ())
# With graphs
print ( requests . post ( 'http://localhost/openccg/parse' ,
data = { 'sentence' : 'Take the cup.' },
params = { 'graphs' : True }). json ())
نظرًا للطريقة التي نستضيف بها OpenCCG خلف nginx at litmus، فإن عناوين URL الخاصة بـ web-openccg جميعها مسبوقة بـ "openccg". ومع ذلك، بالنسبة لنقطتي النهاية المهمتين ( /
لواجهة المستخدم الرسومية و /parse
لواجهة برمجة التطبيقات)، هناك عمليات إعادة توجيه مطبقة. بالنسبة إلى تجعيد هذا يعني curl -L --data "Take the cup." localhost/parse
سيعمل curl -L --data "Take the cup." localhost/parse
أيضًا (لاحظ الوسيطة -L
( --location
)).
لاحظ أنه ليس جاهزًا للإنتاج، لأنه بطيء حقًا وغير محسّن: بدلاً من الاحتفاظ بمثيل واحد (أو عدة) من OpenCCG قيد التشغيل للاستعلام عنها بشكل أسرع، يولد كل طلب مثيل OpenCCG فرديًا.
للاستعلام عن الخدمة بشكل مرئي، ما عليك سوى فتح المتصفح على http://localhost/openccg. بخلاف ذلك، استخدم طلبات cur أو wget أو python على سبيل المثال للاستعلام عن web-openccg عبر سطر الأوامر أو التطبيق الخاص بك.
إذا كان عميلك يسمح ببناء نص الطلب يدويًا، مثل الضفيرة، فما عليك سوى وضع الجملة بداخله:
curl --data "Take the cup." localhost/openccg/parse
ومع ذلك، فإن العديد من الأطر عالية المستوى مثل طلبات بايثون تستخدم عادةً آلية القيمة الرئيسية للبيانات المنشورة. في هذه الحالة، استخدم sentence
الرئيسية:
requests.post('http://localhost/openccg/parse', data={'sentence': 'Take the cup.'})
على سبيل المثال، انظر أدناه.
الاستجابة عبارة عن كائن JSON وتحتوي دائمًا على هذه الحقول:
version
: إصدار كائن JSON.application
: دائمًا "web-openccg"، يكون هذا مفيدًا إذا قمت بتجميع التحليلات من خدمات مختلفة.uuid
: معرف فريد لهذه الاستجابة. سيكون هذا مفيدًا فقط إذا كنت تخطط لدمج الأداة بطريقة ما.http_status
: حالة HTTP من الطلب.إذا تم تقديم جملة أثناء الطلب، فهذه الحقول موجودة:
sentence
: جملة الإدخال المنظفة (كلها صغيرة، تمت إزالة علامات الترقيم، ...).في حالة وجود تحليل ناجح واحد على الأقل، يتم تضمين هذه الحقول:
parses
: قاموس معرفات التحليل (مثل "np") إلى التحليلات الفعلية عندما يقوم OpenCCG بإخراجها.json_parses
: إصدار من مخرجات OpenCCG بتنسيق JSON مسطح. يتم إنتاج هذا عبر قواعد نحوية مخصصة لـ TatSu. للحصول على التفاصيل انظر أدناه. كل قيمة قاموس فردية عبارة عن قائمة بالأسماء و/أو المتغيرات و/أو الأدوار.graphs
: قاموس معرفات التحليل إلى سلاسل النقاط. يمكن عرضها باستخدام graphviz - واجهة المستخدم الرسومية عبر الإنترنت تعرضها تلقائيًا. ملاحظة: تتم مشاركة المفاتيح بين parses
و json_parses
و graphs
، وبالتالي يمكنك بسهولة البحث عن المخرجات الأصلية لتحليل JSON والعكس.
في حالة حدوث خطأ، يكون حقل الخطأ موجودًا:
error
: وصف الخطأ.الإصدار الحالي: 2.3.0
يمكن تحديد تنسيق JSON لتوزيعات OpenCCG من المثال أعلاه أو من خلال فحص ملف OpenCCG.ebnf المكتوب بالكامل بعناية.
هناك ثلاثة أنواع مختلفة من الكائنات: الاسمية والمتغيرة والدور. يمكن أن تكون المواصفات الدلالية الكاملة (ملف JSON) إما كيانًا واحدًا من أي من الأنواع الثلاثة أو قائمة من الأسماء الاسمية. إذا وجدنا التحليلات وهي عبارة عن قوائم للمتغيرات أو الأدوار، فسيتم توسيع القواعد النحوية. يرجى فتح مشكلة إذا وجدت جملًا لا يمكن تحليلها بشكل صحيح.
الاسمي يشبه المتغير الخاص، فهو يصف "الموضوع الرئيسي" للجملة. نظرًا لأنهما متماثلان عمليًا (لهما في الواقع قواعد تحليل متشابهة جدًا)، فإن تنسيق JSON يمثلهما ببنية متطابقة:
{
"__class__" : " Variable " ,
"name" : " x1 " ,
"type" : " gum-OrientationChange " ,
"roles" : []
}
__class__
إما Variable
أو Nominal
.name
هو المتغير المسمى الذي يستخدمه OpenCCG، وهو عبارة عن حرف متبوعًا برقم، على سبيل المثال x1
أو w12
.type
هو محدد GUM يشير إلى نوع المتغير. ويمكن أيضًا أن يكون null
، إذا لم يتم تحديد النوع.roles
هي قائمة الأدوار كما هو موضح أدناه. يحدد الدور جميع الخصائص التي يمكن أن يمتلكها المتغير أو الاسمي. يتبع بنية مشابهة جدًا:
{
"__class__" : " Role " ,
"type" : " quant " ,
"target" : ...
}
__class__
: Role
.type
: نوع الدور. هذا يحدد احتمالات target
.target
: قيمة الدور. يمكن أن يكون هذا عدة أشياء مختلفة، انظر أدناه. إذا كان النوع entity
، فسيكون الهدف مثيلًا، مثل "cup" أو "slm-Taking". إذا كان النوع يحتوي على بادئة متبوعة بشرطة، على سبيل المثال gs-hasSpatialModality
أو gs-direction
، فسيكون الهدف Variable
؛ في البومة سيكون هذا ObjectProperty. إذا كان النوع عبارة عن سلسلة أخرى، فسيكون الهدف عبارة عن سلسلة ذرية، على سبيل المثال، يمكن أن يكون للنوع det
the
، بينما يمكن أن يكون للنوع quant
الهدف singular
.
تستخدم معظم خدمات الويب المنفذ 80 كمنفذ افتراضي، وكذلك يفعل web-openccg.
لتغيير المنفذ، اضبط ملف إنشاء عامل الإرساء وقم بتغيير خط المنفذ من "80:80"
إلى المنفذ الخاص بك على الجانب الأيسر (ولكن احتفظ بـ 80 على اليمين)، لذلك على سبيل المثال لإعداد الخدمة على المنفذ 9043 ، يمكنك تغييره إلى "9043:80"
.
قبل البدء في التطوير، تحتاج إلى إنشاء حاوية عامل الإرساء باستخدام:
make build
تتضمن هذه الخطوة أيضًا بعض الملفات التي تم تنزيلها أثناء عملية الإنشاء إلى الدليل المحلي ./webopenccg/static. يتم إجراء النسخ لأن خادم التطوير يقوم بتحميل الدليل، الذي يقوم بالكتابة فوق الملفات المتوفرة فقط داخل الحاوية ولكن ليس على النظام المضيف.
لبدء حاوية تطوير عامل الإرساء، استخدم ملف Makefile:
make run
يرتبط خادم التطوير بالمنفذ 5000 ويستخدم بيئة تصحيح الأخطاء للقارورة. بالإضافة إلى ذلك، تقوم حاوية الإرساء التي بدأت بـ make run
بربط دليل التطبيق بحيث تعمل إعادة تحميل القارورة بشكل صحيح.
لتجميع قواعد OpenCCG.ebnf، قم بتشغيل:
make
مثال على الرد على جملة "خذ الكأس". يكون:
{
"version" : " 2.2.0 " ,
"application" : " web-openccg " ,
"uuid" : " ecae8222-af9b-4185-a508-efa8be33c7e6 " ,
"sentence" : " take the cup " ,
"parses" : {
"smain" : " @x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking)) " ,
"smain/0" : " @x1:gum-OrientationChange( <mood>imp ^ <gs-direction>(x2:gs-GeneralizedLocation ^ <gs-hasSpatialModality>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular)) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking)) " ,
"smain/.r" : " @x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Moving ^ slm-Taking)) " ,
"smain/.r/0" : " @x1:gs-AffectingDirectedMotion( <mood>imperative ^ <gs-route>x2 ^ <gum-actee>(w2:slm-Cup ^ cup ^ <det>the ^ <ident>specific ^ <quant>singular) ^ <gum-processInConfiguration>(w0:slm-Taking ^ slm-Taking)) "
},
"http_status" : 200 ,
"json_parses" : {
"smain" : {
"__class__" : " Nominal " ,
"type" : " gum-OrientationChange " ,
"name" : " x1 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " mood " ,
"target" : " imp "
},
{
"__class__" : " Role " ,
"type" : " gs-direction " ,
"target" : {
"__class__" : " Variable " ,
"type" : " gs-GeneralizedLocation " ,
"name" : " x2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " gs-hasSpatialModality " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Cup " ,
"name" : " w2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " cup "
},
{
"__class__" : " Role " ,
"type" : " det " ,
"target" : " the "
},
{
"__class__" : " Role " ,
"type" : " ident " ,
"target" : " specific "
},
{
"__class__" : " Role " ,
"type" : " quant " ,
"target" : " singular "
}
]
}
}
]
}
},
{
"__class__" : " Role " ,
"type" : " gum-processInConfiguration " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Moving " ,
"name" : " w0 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " slm-Taking "
}
]
}
}
]
},
"smain/0" : {
"__class__" : " Nominal " ,
"type" : " gum-OrientationChange " ,
"name" : " x1 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " mood " ,
"target" : " imp "
},
{
"__class__" : " Role " ,
"type" : " gs-direction " ,
"target" : {
"__class__" : " Variable " ,
"type" : " gs-GeneralizedLocation " ,
"name" : " x2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " gs-hasSpatialModality " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Cup " ,
"name" : " w2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " cup "
},
{
"__class__" : " Role " ,
"type" : " det " ,
"target" : " the "
},
{
"__class__" : " Role " ,
"type" : " ident " ,
"target" : " specific "
},
{
"__class__" : " Role " ,
"type" : " quant " ,
"target" : " singular "
}
]
}
}
]
}
},
{
"__class__" : " Role " ,
"type" : " gum-processInConfiguration " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Taking " ,
"name" : " w0 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " slm-Taking "
}
]
}
}
]
},
"smain/.r" : {
"__class__" : " Nominal " ,
"type" : " gs-AffectingDirectedMotion " ,
"name" : " x1 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " mood " ,
"target" : " imperative "
},
{
"__class__" : " Role " ,
"type" : " gs-route " ,
"target" : {
"__class__" : " Variable " ,
"type" : null ,
"name" : " x2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " gum-actee " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Cup " ,
"name" : " w2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " cup "
},
{
"__class__" : " Role " ,
"type" : " det " ,
"target" : " the "
},
{
"__class__" : " Role " ,
"type" : " ident " ,
"target" : " specific "
},
{
"__class__" : " Role " ,
"type" : " quant " ,
"target" : " singular "
}
]
}
},
{
"__class__" : " Role " ,
"type" : " gum-processInConfiguration " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Moving " ,
"name" : " w0 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " slm-Taking "
}
]
}
}
]
}
}
]
},
"smain/.r/0" : {
"__class__" : " Nominal " ,
"type" : " gs-AffectingDirectedMotion " ,
"name" : " x1 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " mood " ,
"target" : " imperative "
},
{
"__class__" : " Role " ,
"type" : " gs-route " ,
"target" : {
"__class__" : " Variable " ,
"type" : null ,
"name" : " x2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " gum-actee " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Cup " ,
"name" : " w2 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " cup "
},
{
"__class__" : " Role " ,
"type" : " det " ,
"target" : " the "
},
{
"__class__" : " Role " ,
"type" : " ident " ,
"target" : " specific "
},
{
"__class__" : " Role " ,
"type" : " quant " ,
"target" : " singular "
}
]
}
},
{
"__class__" : " Role " ,
"type" : " gum-processInConfiguration " ,
"target" : {
"__class__" : " Variable " ,
"type" : " slm-Taking " ,
"name" : " w0 " ,
"roles" : [
{
"__class__" : " Role " ,
"type" : " entity " ,
"target" : " slm-Taking "
}
]
}
}
]
}
}
]
}
},
"graphs" : {
"smain": "strict graph "" {ntnode [label="\N"];ntsubgraph cluster_x1 {nttgraph [fillcolor=lightskyblue,ntttlabel="x1: gum-OrientationChange",ntttstyle=filledntt];nttsubgraph "cluster_gs-direction" {ntttgraph [fillcolor=honeydew,nttttlabel="gs-direction",nttttstyle=fillednttt];ntttsubgraph cluster_x2 {nttttgraph [fillcolor=lightblue,ntttttlabel="x2: gs-GeneralizedLocation",ntttttstyle=filledntttt];nttttsubgraph "cluster_gs-hasSpatialModality" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gs-hasSpatialModality",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w2 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w2: slm-Cup",ntttttttstyle=filledntttttt];nttttttw2tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> cup|<det> the|<ident> specific|<quant> singular}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttt}ntt}nttsubgraph "cluster_gum-processInConfiguration" {ntttgraph [fillcolor=honeydew,nttttlabel="gum-processInConfiguration",nttttstyle=fillednttt];ntttsubgraph cluster_w0 {nttttgraph [fillcolor=lightblue,ntttttlabel="w0: slm-Moving",ntttttstyle=filledntttt];nttttw0tttt [fillcolor=aliceblue,ntttttlabel="{<entity> slm-Taking}",ntttttshape=Mrecord,ntttttstyle=filled];nttt}ntt}nttx1tt [fillcolor=aliceblue,ntttlabel="{<mood> imp}",ntttshape=Mrecord,ntttstyle=filled];nt}n}n",
"smain/0": "strict graph "" {ntnode [label="\N"];ntsubgraph cluster_x1 {nttgraph [fillcolor=lightskyblue,ntttlabel="x1: gum-OrientationChange",ntttstyle=filledntt];nttsubgraph "cluster_gs-direction" {ntttgraph [fillcolor=honeydew,nttttlabel="gs-direction",nttttstyle=fillednttt];ntttsubgraph cluster_x2 {nttttgraph [fillcolor=lightblue,ntttttlabel="x2: gs-GeneralizedLocation",ntttttstyle=filledntttt];nttttsubgraph "cluster_gs-hasSpatialModality" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gs-hasSpatialModality",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w2 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w2: slm-Cup",ntttttttstyle=filledntttttt];nttttttw2tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> cup|<det> the|<ident> specific|<quant> singular}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttt}ntt}nttsubgraph "cluster_gum-processInConfiguration" {ntttgraph [fillcolor=honeydew,nttttlabel="gum-processInConfiguration",nttttstyle=fillednttt];ntttsubgraph cluster_w0 {nttttgraph [fillcolor=lightblue,ntttttlabel="w0: slm-Taking",ntttttstyle=filledntttt];nttttw0tttt [fillcolor=aliceblue,ntttttlabel="{<entity> slm-Taking}",ntttttshape=Mrecord,ntttttstyle=filled];nttt}ntt}nttx1tt [fillcolor=aliceblue,ntttlabel="{<mood> imp}",ntttshape=Mrecord,ntttstyle=filled];nt}n}n",
"smain/.r": "strict graph "" {ntnode [label="\N"];ntsubgraph cluster_x1 {nttgraph [fillcolor=lightskyblue,ntttlabel="x1: gs-AffectingDirectedMotion",ntttstyle=filledntt];nttsubgraph "cluster_gs-route" {ntttgraph [fillcolor=honeydew,nttttlabel="gs-route",nttttstyle=fillednttt];ntttsubgraph cluster_x2 {nttttgraph [fillcolor=lightblue,ntttttlabel=None,ntttttstyle=filledntttt];nttttsubgraph "cluster_gum-actee" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gum-actee",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w2 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w2: slm-Cup",ntttttttstyle=filledntttttt];nttttttw2tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> cup|<det> the|<ident> specific|<quant> singular}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttttsubgraph "cluster_gum-processInConfiguration" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gum-processInConfiguration",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w0 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w0: slm-Moving",ntttttttstyle=filledntttttt];nttttttw0tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> slm-Taking}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttt}ntt}nttx1tt [fillcolor=aliceblue,ntttlabel="{<mood> imperative}",ntttshape=Mrecord,ntttstyle=filled];nt}n}n",
"smain/.r/0": "strict graph "" {ntnode [label="\N"];ntsubgraph cluster_x1 {nttgraph [fillcolor=lightskyblue,ntttlabel="x1: gs-AffectingDirectedMotion",ntttstyle=filledntt];nttsubgraph "cluster_gs-route" {ntttgraph [fillcolor=honeydew,nttttlabel="gs-route",nttttstyle=fillednttt];ntttsubgraph cluster_x2 {nttttgraph [fillcolor=lightblue,ntttttlabel=None,ntttttstyle=filledntttt];nttttsubgraph "cluster_gum-actee" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gum-actee",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w2 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w2: slm-Cup",ntttttttstyle=filledntttttt];nttttttw2tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> cup|<det> the|<ident> specific|<quant> singular}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttttsubgraph "cluster_gum-processInConfiguration" {ntttttgraph [fillcolor=honeydew,nttttttlabel="gum-processInConfiguration",nttttttstyle=fillednttttt];ntttttsubgraph cluster_w0 {nttttttgraph [fillcolor=lightblue,ntttttttlabel="w0: slm-Taking",ntttttttstyle=filledntttttt];nttttttw0tttttt [fillcolor=aliceblue,ntttttttlabel="{<entity> slm-Taking}",ntttttttshape=Mrecord,ntttttttstyle=filled];nttttt}ntttt}nttt}ntt}nttx1tt [fillcolor=aliceblue,ntttlabel="{<mood> imperative}",ntttshape=Mrecord,ntttstyle=filled];nt}n}n"
}
}
مثال للتصور (يظهر الرئيسي فقط):