الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تصميم كمبايلر مرحلة parser

مغلق
بدأه تالا في 30 نوفمبر 2004 · 24 رد · 2,493 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

اخواني سبق وان طلبت منكم مساعدات في برنامج تصميم كمبايلر

بلغة c++

وما قصرتوا

وهذا الشي خلاني ارجعلكم مرة ثانية في مرحلة parser او syntax analyzer

فرجاء اللي عنده اي مساعدة بهالموضوع لان عندي شوية اسألة محيرتني بكيفية

بداية كتابتي للبرنامج...

الوقت المطلوب تنفيذ البرنامج خلاله قصير جدا

يعني لازم بعد اسبوعين لازم يكون البرنامج جاهز...

فرجاء لاتتاخرون علي بالردود...

ومشكورين مقدما....

#2

السلام عليكم

اهلا اختي تالا .

هذه المرحلةتعنى بقواعد النحو فمأدريماهي الطريقة التي تتبعونها في تصميم parser

يعني هل هنالك قواعد تنطلقون منها في التصميم أم ماذا.

أريد توضيح أكثر وان شاء الله نحاول نساعدك على مأضن ان برنامج اخي فلسطينية السابق كان حاوي على ماضن كلا المرحلتين المحلل المفرداتي والنحوي .

بالتوفيق

اذا كنتم تتبعون القواعد النحوية فكتبيها هنا.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#3

السلام عليكم و رحمة الله و بركاته

الموضوع ده شيق بالنسبة لي

انا معاكي

قوللي الاول هل فيه لغة معينة هل يمكن الاستعانة ببعض الComponents

هل عندك Tokneizer

علي فكرة انا عملت Semantic Parser من قبل بس لم انشره الي الان

تم تعديل هذه المشاركة بواسطة mdyehia في 1 ديسمبر 2004 في 17:06

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#4

الاخت madyehia

المطلوب منا هو مرحلة syntax analyzer

احنا نفذنا مرحلة lexical analyzer

اما بالنسبة للاخ السهم الناري

E -> T E'

E' -> + T E' | ε

T -> F T'

T' -> * F T' | ε

F -> (E) | id

وهي right recursive للنحو الاساسي

E -> E + T | T

T -> T * F | F

F -> (E) | id

#5

عفوا انا موقع أبو المنذر فكيف تقول الاخت؟

طيب

ممكن الان نحدد الهدف

و هو برنامج لمعرفة مصطلح رياضى هل تم كتابته بطريقة سليمة أم لا

بمعني آخر كوبيلر للمصطلحات الرياضية

و هذا مستنبط من ال Grammer

هل انا فاهم المشكلة صح

انا فقط ركزت علي المصطلحات الرياضية

انا فهمت من أول وهلة انه كومبيلر كامل

تم تعديل هذه المشاركة بواسطة mdyehia في 2 ديسمبر 2004 في 15:41

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#6

الاخ ابو المنذر اعتذر عن الخطأ الغير مقصود

البرنامج هو جزء من الكمبايلر وهو جزء ال parser فقط

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

مثلا

id+id(id*id)

والمخرجات هي شجرة النحو او parser tree

ورسالة توضح هل المدخل طابق قواعد الاعراب ام لا

#7

لا عليك يمكن اكون مخطأ في اختيار الاسم

اقتباس
ملحوظة انا أحب التبسيط في حل المشاكل بمعني ننجز الشئ البسيط و بعد ذلك نعقد الدنيا زي ما احنا عاوزين

لكي ننجز نبسط الموضوع في الاول

إحنا محتاجين مجموعة الفنكشن الآتية

IsExpr()

IsTerm()

IsOperator()

IsRightBracket()

IsLeftBracket()

وأكيد انت عندك Tokenizer اللي المفروض يعطي لنا List من الTokens

و للنبسيط أكثر ممكن الGrammer يكون Static بمعني انه مكتوب داخل البرنامج

و يكون الفنكشن

int IsExpr(char * str){

// نحول الchar * الي array باستخدام Tokeizer 

if(Tokeizer.conut=0) return false;

if(Tokeizer.conut=1)
	if (IsTerm(Tokeizer[0])) return true;// يحقق E -> T

for(int i=0; i<Tokeizer.conut-1;i+=3){
	if (IsExpr(Tokeizer) && IsOperator(Tokeizer[i+1]) && IsExpr(Tokeizer[i+2]))
   return true; // يحقق E -> E + T 
               // يحقق E -> E * T | T
       // يحقق E -> E - T | T
	if (IsRightBracket(Tokeizer) && IsOperator(IsTerm[i+1]) &&        IsLeftBracket(Tokeizer[i+2]))
   return true; // يحقق E -> (T)

}
return false;
}

تم تعديل هذه المشاركة بواسطة mdyehia في 4 ديسمبر 2004 في 13:38

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#8

شكرا اخ ابو المنذر

لكن مطلوب منا ان نستخدم جدول النحو

parsing table for grammer

والمشكلة عندي في كيفية تكوين هذا الجدول...

وهو لنفس القواعد المذكورة....

انا لم افهم هذه الخطوة التي ذكرتها

لكن سوف احاول تطبيقها والرد عليك لاحقا..

#9

السلام عليكم و رحمة الله و بركاته

احنا مش هنعرف نحل المشاكل مرة واحدة

خللي المشكلة parsing table for grammer بعدين

اقتباس
و للنبسيط أكثر ممكن الGrammer يكون Static بمعني انه مكتوب داخل البرنامج

نصمم البرنامج و نوحد المفهوم أولا

فكرة الفنكشن دي هي تراجع و تصحح الExpr

و تعتبر هي ال Main Function

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#10

يعني هذه الخطوات تغنينا عن الجدول؟

#11

يعني هذه الفنكشن تغنينا عن الجدول؟

#12

نعم

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#13

اعتذر عن التأخر عن الرد لكن أنا أتكفل بالبرنامج المذكور أعلاه

إذا كنت تريد قيمة التعبير !

ماهي طريقة تعريف ال ID وتحديد قيمته

إذا كنت تريد فقط التحقق من مدخلات المستخدم فهذا سهل!

قريباً أرفق الكود...

#14

شكرا لتعاونك اخ موسى

#15

هذا البرنامج يقوم ب parse للملف و عمل syntax Tree لل expretion

أعتذر لأني مشغول ضغطت نفسي هذة الليلة عليه إذا كان البرنامج غير واضح

لكن إذا فيه أي إستفسار أو تعديل فأنا مستعد لذلك

الكود

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

typedef enum 
    /* book-keeping tokens */
{   DONE,
    /* multicharacter tokens */
    ID,NUM,
    /* special symbols */
    PLUS,MINUS,MUL,DIV,LPAREN,RPAREN
} TokenType;

typedef enum {opK, constK, idK} ExpKind;
typedef struct treeNode
{  struct treeNode * left;
  struct treeNode * right;

  union { int op;
      int val;
      char * name; } attr;
  int kind;
} TreeNode;

#define BUF_SIZE 32
char buf[BUF_SIZE]; /* buffer to lex token */
int  tokenval;
int  token;
FILE* in;

void error (char* msg);
void match (int t);

TreeNode* newExpNode(int kind);
char * copyString(char * s);

TreeNode* exp();
TreeNode* term();
TreeNode* factor();
TreeNode* parse ();

void pre(TreeNode* t, int w);


int getToken()
{
  char t;             /* current char        */
  int b = 0;            /* curser to buffer    */

  while(1)
  { t = getc(in);
	/* ign tab & space in source */
    if((t == '\t')||(t == ' ')||(t == '\n'));


	/* for KEYWORDs & IDs */
    else if(isalpha(t))
   { while(isalpha(t) || isdigit(t))
     {	buf[b++] = t; t = getc(in); }
     ungetc(t,in);
     buf='\0';

     return ID; 
   }

	/* for number */
    else if(isdigit(t))
   { ungetc(t,in);
  	fscanf (in, "%d", &tokenval);
     return NUM;
   }

	/* END OF FILE*/
    else if(t == EOF) return DONE;

	/* OTHERs*/
    switch(t)
  {
  case '+': return PLUS;
  case '-': return MINUS;
  case '*': return MUL;
  case '/': return DIV;
  case '(': return LPAREN;
  case ')': return RPAREN;
  }
  }
}



void error (char* msg)
{
	printf ("Error : %s\n", msg);
	exit(3);
}

void match (int t)
{
	if (t == token)
  token = getToken();
	else
  error("Syntax Error");
}

/* Function copyString allocates and makes a new
 * copy of an existing string
 */
char * copyString(char * s)
{ int n;
  char * t;
  if (s==NULL) return NULL;
  n = strlen(s)+1;
  t = (char*) malloc(n);
  strcpy(t,s);
  return t;
}

TreeNode* newExpNode(int kind)
{
	TreeNode* t = (TreeNode*) malloc(sizeof(TreeNode));
	t->kind = kind;
	t->left = 0;
	t->right = 0;
	return t;
}

TreeNode* exp()
{
	TreeNode* t = term();
	while ((token == PLUS) || (token == MINUS))
	{ TreeNode* p = newExpNode(opK);
  if (p)
  {
  	p->left = t;
  	p->attr.op = token;
  	t = p;
  	match(token);
  	p->right = term();
  }
	}
	return t;
}

TreeNode* term()
{
	TreeNode* t = factor();
	while ((token == MUL) || (token == DIV))
	{ TreeNode* p = newExpNode(opK);
  if (p)
  {
  	p->left = t;
  	p->attr.op = token;
  	t = p;
  	match(token);
  	p->right = factor();
  }
	}
	return t;
}

TreeNode* factor()
{
	TreeNode* t = 0;
	switch (token){
  case NUM:
  	t = newExpNode(constK);
  	t->attr.val = tokenval;
  	match(NUM);
  	break;

  case ID:
  	t = newExpNode(idK);
  	t->attr.name = copyString(buf);
  	match(ID);
  	break;

  case LPAREN:
  	match(LPAREN);
  	t = exp();
  	match(RPAREN);
  	break;

  default:
  	error("Syntax Error");
	}
	return t;
}

TreeNode* parse ()
{
	TreeNode* t;
	token = getToken();
	t = exp();
	return t;
}

void pre(TreeNode* t, int w)
{
	if (t){
  pre (t->left, w+1);

  for (int i = 0; i<w; i++)
  	printf("\t");
  switch(t->kind)
  {
  case opK:
  	switch (t->attr.op){
  	case PLUS: printf("+\n"); break;
  	case MINUS: printf("-\n"); break;
  	case MUL: printf("*\n"); break;
  	case DIV: printf("/\n"); break;
  	}
  	break;
  case constK:
  	printf("%d\n", t->attr.val);
  	break;
  case idK:
  	printf("%s\n", t->attr.name);
  	break;
  }

  pre (t->right, w+1);
	}
}

void main(int argc, char** argv)
{
	if (argc != 2)
	{
  printf("USAGE : EXP[.exe] filename\n");
  exit(1);
	}
	in = fopen(argv[1], "r");
	if (!in)
	{
  printf("Can't open file\n");
  exit(0);
	}

	TreeNode* t;
	t = parse();
	pre(t, 0);

}

يمكنك ترجمة السابق على ملف يحتوي على

(m+y)*(5+4)/50

تم تعديل هذه المشاركة بواسطة mossa في 5 ديسمبر 2004 في 23:31

#16

السلام عليكم و رحمة الله و بركاته

أخي العزيز mossa

أظن ان كتابة البرنامج مرة واحدة بصورة كاملة لا تجعل أعضاء المنتدي يستفيدوا خصوصا اصحاب المشكلة

انما جهد وافر تشكر عليه

نصيحة غالية أقولها لاحبابي فقط (أعضاء المنتدي) لا تصمم هيكل لل Tree و تعمل لها Methods

الكلام ده تلاقيه ببلاش في TreeView أعمل Instance منها في الكود و تعرف تضيف Node و تحذف أخري

و تعرف الاب و تعرف الابناء و هكذا

تم تعديل هذه المشاركة بواسطة mdyehia في 6 ديسمبر 2004 في 11:23

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#17

شكرا اخ موسى

سأجرب الكود واعطيك الرد لاحقا

#18

أشكوا من ضيق الوقت

لكن كما قلت أنا مستعد بإذن الله لأي أسئلة

treeview الموجودة في C++ معقدة جدا لذلك وضعت الtree السابقة لسهولة التعامل

وإذا لم ترضكم مشاركتي أو كانت معقدة إعتبرها لاغية "أهم شيء الفائدة للجميع سواء بمشاركتي أو بدونها"

وأشكركم جميعاً

#19

السلام عليكم و رحمة الله و بركاته

أخي العزيز mossa

انا اسف علي العموم

ومرة ثانية أقول لك هذا جهد وافر تشكر عليه

جزاك الله خيرا

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#20

الاخ موسى

اشكرك عالمساعدة لكن انا شفت الكود معقد شوي

الاخ ابو المنذر

الكود مفهوم مبدئيا لكن ما المقصود ب tkenaizer

??

#21

مجموعة الTokens التي في ال Expression بالاضافة الي نوعها

تم تعديل هذه المشاركة بواسطة mdyehia في 8 ديسمبر 2004 في 13:22

المسلمون ربهم واحد و قبلتهم واحدة و كتابهم واحد

و يقفون يوم الحج الاكبر بملبس متشابه في صعيد واحد

و يصلون الجمعة و الجماعات

كل ذلك و قلوبهم متفرقة

اللهم اجمع شمل المسلمين و ألف بين قلوبهم

أبو المنذر

#22

السلام عليكم

عفوا وعذرا على تاخير الرد لكن ماشاء الله الاخوان ماقصروا معكي تالا لكن صدقيني المشكلة تكمن في الوقت ماعنديوقت اتصفح المنتدى بسبب تقديم الاختبارات وتسليم مشاريع وغيره...

المهم حبيت اضيف اضافة بسيطة

وهي الطريقة التي استخدمناها في قاعات الدراسة .

المحلل المفرداتي lexel anlayzer مهمته القراءة حرفا حرفا وتكوين سلسلة يعطيها توكن معين مثلا السماء ID والاعداد NUM

وهكذا.

اما المحلل النحوي فمهمته توضيح ماذا المدخل الذي كتبه المستخدم صحيح مطابق للقواعد النحوية ام لا.

ويتم تصميمه بسهوله

حيث كل رمز لانهائي nonterminal في القواعد يكون اسم للدالة وكل رمز نهائي نعمل له قراءة من بعد للمحلل المفرداتي لرؤية التوكن الاخر وهكذا ويمكن وضع دالة تقوم بمقارنة التوكن اذا كان هو مأريده ( اقصد التوكن الذي من المفروض ان نقراه من المستخدم ).

نعم قراءة جديدة

الدالة match

void match( int t )

{

if( token == t )

token = lexen();

else

//اطبع خطأ ليس هو التوكن المطلوب

}

ولتكن عندنا القاعدة التالية

E -> + T

T -> NUM | ID

فتكون الدوال على الشكل التالي

void E()

{

token = lexen();

if( token == '+' )

T();

else

\\طباعة رسالة خطأ

}

void T()

{

token = lexen();

switch( token)

{

case NUM:

case ID:

// نفذ قاعدة معينه وهكذا نستمر حتى نهاية القواعد

default:

break;

}

وهكذا نتابع

لولا ضيق الوقت لكملت ماردت قوله ولكن الشكوى لله.

بالتوفيق.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#23

يوجد كورس كامل يشرح طريقة بناء الكومبيلر

علي الرابط التالي

Compiler Construction

لاحظ أنه يتناول شرح طريقة العمل من خلال لغة الجافا

والسلام عليكم

29_5.gif

سورة العنكبوت

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

مشروع Arabic PHP.NET

حلم طالما كان يراودني حتي قهرته بحمد الله ليكون حقيقة

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

سلسلة أنماط التصاميم البرمجية Desgin Patterns

سلسلة أنماط التصاميم البرمجية Desgin Patterns | كتيب هذه الدروس (إعداد أحمد غريب)

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

كنترول ASP.NET DataGrid CheckBoxColumn

كنترول ProgressBar

كنترول UltraPanel

مشروع الكنترول الأنيق (إهداء للفريق العربي)

الورش الإلكترونية IT Workshops

تعقب الأخطاء error tracing

كنترول ColorPicker لمطوري الويب

RichTextBox Control لمطوري ال ASP.Net

حمل كتاب جافا سكربت عربي

#25
اقتباس
هل يمكن بناك معالج يدعم اللغه العربيه

نعم يمكنك عمل ذلك

29_5.gif

سورة العنكبوت

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

مشروع Arabic PHP.NET

حلم طالما كان يراودني حتي قهرته بحمد الله ليكون حقيقة

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

سلسلة أنماط التصاميم البرمجية Desgin Patterns

سلسلة أنماط التصاميم البرمجية Desgin Patterns | كتيب هذه الدروس (إعداد أحمد غريب)

ـــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــــ

كنترول ASP.NET DataGrid CheckBoxColumn

كنترول ProgressBar

كنترول UltraPanel

مشروع الكنترول الأنيق (إهداء للفريق العربي)

الورش الإلكترونية IT Workshops

تعقب الأخطاء error tracing

كنترول ColorPicker لمطوري الويب

RichTextBox Control لمطوري ال ASP.Net

حمل كتاب جافا سكربت عربي

هذا الموضوع مغلق.

مواضيع مشابهة