التعابير النظامية: أداة ناجعة في يد المترجم

يصطدم المترجم التقني في عمله اليومي بالعديد من المهام الروتينية التي قد تتحول إلى عقبات مؤرقة إن لم يلجأ لبعض التقنيات العملية. من بين هذه التقنيات، نجد "التعابير النظامية" التي توفر على صاحبها الكثير من الوقت والجهد في حالة استخدامها بشكل سليم.

تتكون التعابير النظامية من مجموعة من الرموز الاصطلاحية المُعَرِّفة للغة. وترتبط هذه التعابير بشكل وثيق باﻵلات المُتناهية اللاحَتْمِيّة[0]. لكن، وعلى خلاف اﻵلات المتناهية التي تسمح بالحصول على وصف لغوي مشابه للآلة، فإن التعابير النظامية توفر وصفاً جَبْرياً للغات. لمعرفة المزيد عن الخلفية الرياضية لهذا النمط من التعابير، يرجى الاطلاع على المرجع[1] المذكور أدناه.
تُستَخدم التعابير النظامية في العديد من التطبيقات الحاسوبية، بما في ذلك أوامر البحث في أنظمة جنو/لينكس ومحركات قواعد البيانات وأدوات توليد المُحلِّلاتِ اللفظية. تكمن قوة هذه التعابير في سماحها للمستخدم بالقيام بالعديد من العمليات التي قد يتطلب إنجازها وقتاً كبيراً في حالة اللجوء للطرق التقليدية، كما سنرى في أمثلة لاحقة. لكن، قبل أن نبدأ، يجب الإشارة إلى أن التعابير النظامية تستخدم قواعد نحويّة معينة ترتكز بدورها على سلسلة من اﻷحرف الوصفية الخاصة التي يختلف معناها باختلاف اﻷدوات واللغات البرمجية المستخدمة.

يخضع استخدام التعابير النظامية لقاعدتين أساسيتين:

القاعدة اﻷولى: مجال تطبيق التعبير النظامي يتوقف دائماً عند نهاية السطر.
حسب هذه القاعدة، فإننا لن نجد أبداً عبارة نظامية تتضمن حرف "سطر جديد"، أي أن هذا النوع من العبارات غير قابل للصياغة. ففي حالة البحث عن كلمة مركبة مثل week-end في نص معين، فإن البرنامج لن يعثر على المواضع المشكلة من -week في نهاية السطر وend في بداية السطر الموالي.
القاعدة الثانية: في حالة تطابق التعبير النظامي مع سلاسل حرفية متعددة في سطر ما، فإن التطابق الذي سيُأخّذُ بعين الاعتبار سيكون دائماً هو التطابق اﻷطول (في حالة وجود تطابقات متعددة من نفس الطول، سوف يُأخذ التطابق اﻷول).

بنية التعابير النظامية

تخضع التعابير النظامية لتركيبٍ نَحْويٍّ دقيق، حيث ترتكز بنيتها على القواعد التالية:
ا. إذا كان x1 وx2 تعبيرين نظاميين، فإن العبارة x1x2 ستكون بدورها تعبيراً نظامياً (مبدأ الوصل). في هذه الحالة، فإن وصل x1 بـ x2 يتم بدون استخدام أي حرف فاصل بين التعبيرين.
ب. كل حرف من أحرف ASCII يُعتبر حرفاً نظامياً، مما يعني بأن كل حرف لا يتطابق إلا مع نفسه في السطر الواحد، ما عدا إذا كان اﻷمر يتعلق بأحد الرموز الخاصة التالية:
? + \ | { } ( ) [ ] . * - $ ^
استخدام الشرطة المائلة الخلفية "\" يسمح بإبطال مفعول الرموز الخاصة ومعاملتها كأحرف عادية، فإذا قمنا بدمج الشرطة المائلة "\" في العبارة Par\.2، فإن هذه العبارة ستتطابق مع Par.2 في السطر المُعالَج.
ج. النقطة "." رمز نظامي يتطابق مع أي حرف عادي في السطر. فمثلاً، العبارة a.ram تتطابق مع akram وahram وa1ram وهكذا دواليك.
د. إذا كانت c سلسلة حرفية أو مجالاً من أحرف ASCII، مثل a-z، فإن [c] و[c^] تَعْبِِيرَيْنِ نِظَامِيَّيْنِ أيضاً. من خلال ما ذُكِر، يتضح بأن التعبير [c] يتناسب مع أي حرف عادي يتواجد في c بالسطر النصي. بينما يتناسب التعبير [c^] مع كلّ حرفٍ بالسطرلا يتواجدُ فِي c. فمثلاً، فإن التعبير BH]ook] في سَطر مُعيَّن سيتطابق مع Book وHook. تجدر الإشارة هنا إلى أن المعقوفتين [...] لا تدعمان إلا حرفين خاصين وهما حرف ^ كحرف أول، وحرف - في أي مجال ASCII صالح.
ه. إذا كان a تعبيراً نظامياً، فإن التعبير *a سيكون نظامياً بدوره، مما يعني أن التعبير *a سيتطابق مع اﻷسطر التي لا يظهر فيها التعبير a بتاتاً، أو تلك التي يظهر فيها التعبير a بشكل متكرر. تبعاً لهذه القاعدة، فإن التعبير النظامي *e ينطبق على أي سلسلة حروف فارغة (empty string)، كما ينطبق على e وee وeee... إلخ
و. إذا كان a تعبيراً نظامياً، فإن a^ و$a سيكونان تعبيرين نظاميين بدورهما. تنطبق العبارة a^ على أي تعبير نظامي يتواجد في بداية السطر، بينما تنطبق العبارة $a على أي تعبير نظامي يتواجد في نهاية السطر. لاحظ بأن الرمز الخاص ^ يملأ وظيفتين مختلفتين، فإن تم وضعه كحرف أول بين المعقوفتين، فإنه يكون بمثابة رمز نفي (كل اﻷحرف عدا تلك التي تتواجد بين المعقوفتين)، أما إن تم وضعه في بداية العبارة، فإنه يشير إلى بداية السطر. يمكننا فهم هذه القاعدة من خلال التعبير $*[9-0][9-0]^ الذي ينطبق على كافة اﻷسطر التي لا تتكون إلا من أرقام عددية، بدون أي مسافة فارغة ولا حرف جَدْولة. لاحظ أيضاً بأن الرمز * يسمح بأخذ التكرار المنعدم (NULL iteration) بعين الاعتبار.
ز. إذا كان a تعبيراً نظامياً، فإن التعبير (\a)\ سيكون نظامياً بدوره، مما يسمح لنا بوضع التعابير المبحوث عنها بين قوسين، فلا يجب أن ننسى بأن اﻷقواس رموز خاصة تُستَخدَمُ في الشيل (مترجم اﻷوامر في لينكس). وفقاً لهذه القاعدة، فإن التعبير *(\sum\(sum ينطبق على كافة اﻷسطر التي تتضمن تعابير على شاكلة sum أو sumsum أو sumsumsum... إلخ
اﻵن وقد انتهينا من سرد القواعد اﻷساسية للتعابير النظامية، يمكننا المرور إلى بعض اﻷمثلة التطبيقية في نظام جنو/لينكس للتخلص من بعض المهام الروتينية، وهو ما سنقوم به في الجزء الثاني من هذا الموضوع.

------------------------------------------------------------------

[0] http://www.cs.odu.edu/~toida/nerzic/390teched/regular/fa/nfa-definitions.html
[1] Hopcroft, John E.; Motwani, Rajeev; Ullman, D. Jeffrey: Introduction to automata theory, languages and computation — 2nd Ed., 2001, pages 99-112