بسم الله الرحمن الرحيم
السلام عليكم و رحمة الله و بركاته.
احم .. ضمن محاولتي لعمل parser للغة D, كنت بدأت بمشروع لهذا الأمر, من مدة ليست بالبعدية تقريبا .. لكنني توقفت عن تطويره لسبب ما .. ربما لأنني احسست ان الوضع اصبح معقدا بعض الشيء, حيث قمت بعمل الـ lexer و مشي الحال,و لكن عندما جئت للـ parser دخت قليلا ثم انصرفت عن المشروع.
المهم الان, لا اريد ان يذهب جهدي هباءا, لذلك اريد عرض المشروع و شرحه بعض الشيء, لعله يفيد بعض الأشخاص.
بداية ما هو الـ lexer؟
في الحقيقة لا اعرف بالضبط! لكن التعريف الموجود في الـ documentation الخاصة باللغة اللتي أنا بصددها (لغة D) تقول:
lexical analysis The source file is divided up into a sequence of tokens. Special tokens are replaced with other tokens. Special token sequences are processed and removed
يعني ناخذ ملف نصي, و اللذي هو بطبيعة الحال مكون من سلسلة حروف, و نقوم بتحويله الى سلسلة tokens.
هنا سؤال يطرح نفسه, ما هو الـ Token؟
في الحقيقة من الصعب علي الإجابة عن هذا السؤال بشكل محدد .. هناك تعريف في ويكيبيديا
http://en.wikipedia.org/wiki/Token_(parser)
يمكن القول انها وحدة البناء الأساسية في النص, مثلا
if ( someThing ) { doSomeThing(); }مكون من عدة tokens, و هي if يليها القوس ( يليها كلمة someThing .. الخ.
يمكننا اعتبار ان كل "توكن" مكونة من نص و لها نوع (او اسم او وصف ..)
فإذا وضعناها في قائمة ووضعنا وصفا للـ token, فإن الـ tokens الموجودة في الكود السابق هي:
If IF
( OPEN_PARENTHESIS
someThing IDENTIFIER
) CLOSE_PARENTHESIS
{ OPEN_CURLY_BRACE
doSomeThing IDENTIFIER
( OPEN_PARENTHESIS
) CLOSE_PARENTHESIS
; SEMICOLON
} CLOSE_CURLY_BRACEطبعا نحن لسنا ملزمين بهذه التسميات, و لكن هذا مجرد مثال.
تعريف انواع الـ tokens يعتمد على تعريف اللغة نفسها.
الهدف من الـ lexer هو اخذ النص و تحليله الى سلسلة tokens, و هذا هو كل ما اقوم بفعله في البرنامج اللذي أتحدث عنه.
سأقوم إن شاء الله بإرفاق البرنامج, و هذا مثال على تحويل نص الى سلسلة Tokens, حيث يقوم بعرض كل token في سطر لوحدها (ليثبت انه يفهم النص و يستطيع تحويله الى tokens)
المدخلات:
import lex.module_file;
import lex.lexer;
import std.stdio;
void main()
{
Module m = new Module("test_bed.d");
//m.printContent();
TokenizedModule tm = lexical( m );
tm.dumpTokens();
}المخرجات:
import
lex
.
module_file
;
import
lex
.
lexer
;
import
std
.
stdio
;
void
main
(
)
{
Module
m
=
new
Module
(
"test_bed.d"
)
;
TokenizedModule
tm
=
lexical
(
m
)
;
tm
.
dumpTokens
(
)
;
}سأقوم إن شاء الله في المشاركات القادمة بشرح مبسط للكود مع توضيح لبعض الأفكار.
ملاحظة: إذا اردت ترجمة الكود, تحتاج الى dmd compiler إضافة الى build tool
http://www.digitalmars.com/d/dcompiler.html
http://www.dsource.org/projects/build/
بالنسبة للـ build, فاسم الملف يحتوي على رقم الاصدارة, انا شخصيا احذف رقم الاصدارة و اجعل اسم الملف build.exe فقط,و أضعه في الملف ….\dmd\bin و طبعا يجب اضافته الى الـ PATH!! لن اقوم بشرح هذه الأمور هنا, فإذا لم تكن تعرف هذه الأساسيات فليس من المفروض ان تخوض في الموضوع اللذي اتكلم فيه!