Overview

بسم الله الرحمن الرحيم

ملاحظة: صفحة المشروع الرئيسية هنا

خلاصة

    المدخل: "(1 + 1\|2-ن|)"

    المخرج:

        (
            "1 + 1\"
            |
                "2-ن"،
            |
        )

    المدخل: "إجمع(س، ص){ إرجع س+ص }()"
    المخرج:

        "إجمع"
        (
            "س، ص"
        )
        {
            " إرجع س+ص "
        }
        (
            ""
        )

مميزات المكتبة

  • صغر الحجم: لا يتعدى مصدر المكتبة (مع التعليقات وبيان الرخصة والفراقات) ٤٠٠ سطر
  • فحص: تتضمن المكتبة إختبارات متعددة (لتسرب الذاكرة وللسلامة المنطق) لضمان سلامتها (إستخدم make)
  • مرونة: لا يشترط أن يكون المحدد قوسا، يمكنك إستخدام أي سلسلة من المحارف.
  • بساطة الهيكل البياني وإستخراج البيانات منه
  • داعم المحارف العربية: ولأي محارف أخرى عدا الـ"\0" طبعا
  • ملفين فقط (lim.c وlim.h) من دون لوازم ثانوية
  • مكتوبة وفق معيار C99
  • متوافق مع المعايير القديمة (مثل c89)

أساسيات المكتبة

تخزن المكتبة البيانات المستخرجة من المدخلات في سلسلة "عقد".

كل عقدة من هذه العقد تنتمي إلى أحد صنفين: إما عقدة نصية أو عقدة قائمية. العقد النصية تخزن النصوص فقط. أنظر إلى الأمثلة الموجودة في أول الصفحة، كل ما أحيط بعلامتي التنصيص مخزن في هذه العقد.

أما الصنف الآخر، العقد القائمية، فهي تحتوي على قائمة من عقد أخرى (نصية و قائمية).

لعل الرسم التوضيحي التالي أفضل لتوضيح شكل السلسلة:

        ● عقدة نصية
        ○ عقدة قائمية

            ○ ● ● ● ○ ○
              ↓       ↓
            "..."     ● ○ ○ ● ○

هيكل هذه العقد معرف في ملف lim.h بإسم lim_s.

الدالة المسؤولة عن تحويل سلسلة محارف إلى قائمة عقد هي limParse:

    lim_s** limParse(char *s, char **opining_brackets, char **closing_brackets, char **singletons, int *cur);

المدخل الأول للدالة هي سلسلة المحارف المراد فرزها.

المُدخل الثاني والثالث هما قائمتان مختومتان (تنتهيان بـNULL) للفواصل الغير متماثلة، وهذا يشمل الأقواس بأشكالها ((، )، [، ]، <، > ...) و أي سلسلة أخرى، ولا يشترط أن تتكون من حرف واحد.

الشرط الوحيد هو أن تكون القائمتين مختومتين وبنفس الطول.

    char *opining_brackets[] = {"(", "[", "<", NULL};
    char *closing_brackets[] = {")", "]", ">", NULL};

المدخل الرابع هو للفواصل التي يكون رمز البداية مماثل لرمز النهاية (مثل رمز المُطلق الرياضي |) ويكون قائمة مختومة كذلك.

    char *singletons[] = {"|", NULL};

المدخل الأخير هو عنوان المتغير الذي سيستخدم لتخزين عدد البايتات التي خزنتها الدالة في قائمة العقد، وهدفها الأساسي هو تعليم موقع الأخطاء في سلسلة المحارف المدخله؛ إذا وجدت الدالة فاصلا مفتوحا ولم تجد ما يغلقه.

    int cur;

بنسبة إلى مرجع الدالة، فإنها تُرجع قائمة عقد مختومة إذا أتمت عملها أو NULL إذا حال حائل دون إتمام الدالة عملها (نفاد الذاكرة أو خطأ في المدخلات).

إطلع على الملف example.c إذا أردت أن ترى مثال حقيقي وبسيط لكيفية استخدام هذه الدالة.

يجدر بي أن أنبه بأنه يتوجب عليك تحرير مرجع الدالة (قائمة العقد) بعدما تنتهي منه لكي تتجنب تسرب الذاكرة (أو حجزها من دون أن تستفيد منها). يحرر مرجع الدالة بتمريره إلى limFree:

    void limFree(lim_s **s);

التعامل مع قائمة العقد

تحتوي العقد على ثلاثة متغيرات:

  1. متغير لتخزين قوسي البداية والنهاية: brackets
  2. متغير لتخزين النص: text
  3. متغير التخزين قائمة عقد أخرى: list

المتغير الأول لا يحتاج إلى توضيح. والمتغير الثاني لتخزين البيانات النصية (العبارات المحاطة بعلامات التنصيص في الأمثلة الموجودة أول الصفحة). المتغير الثالث لتخزين قائمة عقد مختومة وتحتوي على عقدة واحدة على الأقل.

المتغرين الثاني والثالث متضادان بحيث لا يكونا مستخدمين في نفس العقدة، وهذا ما يحدد نوع العقدة. فإذا كان text مستخدما فإن list تكون خاوية (NULL) وتكون العقدة عند إذ عقدة نصية، وإذا كان الأمر على عكس ذلك، فإن العقدة تكون عقدة قائمية.

لكي تحديد نوع العقدة في البرنامج، لا ينبغي عليك إلا أن تختبر المتغير الثاني أو الثالث مباشرة.

فإذا قلنا ان result مرجع الدالة، وأن القائمة تحتوي على عقدة واحدة على الأقل، فأنك تستطيع أن تحدد هوية العدة الأولى كما يلي:

    if (result[0]->text) fprintf(stderr, "%s: first node is a text node: %s", result[0]->text);

وإذا كانت هويتها قائمية، يمكنك أن تتحقق من هوية أول عقدة فيها:

    else if (result[0]->list[0]->text) printf("first child of first node is a text node: %s", result[0]->list[0]->text);

بيان تفصيلي للدوال في lim.h.

أرجو تبليغي بالمصطلح الصحيح (إن وجد) من خلال خدمة تعقب الأعطاب المشروع: https://bitbucket.org/seininn/lim/issues/new

حقوق النسخ والملكية فكرية

حقوق النشر © 2012 سليمان مصطفى

أنا - صاحب ومؤلف هذه المكتبة - قد رخصتك لنشرا المكتبة والتغيير كما هو موضح في بنود رخصة جنو أفرو العمومية GNU Affero General Public License المرفقة مع المكتبة (الإصدار الثالث) أو الإصدارات التالية منها إن شئت.

(( إتصل بي إن أردت رخصة غير هذه ))

راجع الرخصة نفسها للتفاصيل بنود الترخيص. راجع ملفات المكتبة أيضا.