• 0
وليد جميل

اريد اكتب برنامج بالملفات او بلغة ++c يدخل lexan ويطبع ال token له

سؤال

افيدوني لوسمحتم

اريد اكتب برنامج بالملفات او بلغة ++c يدخل من قبل المستخدم ال lexan ويطبع ال token حقه , مثل for يطبع مقابله (keyword ) ,والمتغيرات (identifire),والعمليات الحسابيه مثل (=) يطبع (equal ) , وبقية الرموز

ارجوا منكم رد سريع

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

4 إجابة على هذا السؤال .

  • 0

هذا مثال على lexer يدوي بسيط يتعرف على for، الأرقام، والرموز "= == ) ( { } ;" يمكنك قراءته وفهمه، والزيادة عليه لاتطلب الكثير:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>/* current status */typedef struct __lex_t {  const char *stream;  char current;} lex_status_t;/* list of tokens */typedef enum __token_t {  TK_ERROR = 0,  TK_FOR,             /* for */  TK_IDENTIFIER,      /* identifier */  TK_NUMBER,          /* [0-9]+ */  TK_EQ,              /* == */  TK_ASSIGN,          /* = */  TK_PARENTHESESO,    /* ( */  TK_PARENTHESESC,    /* ) */  TK_BRACESO,         /* { */  TK_BRACESC,         /* } */  TK_SEMICOLON,       /* ; */  TK_EOF,} token_t;/* keyword type */typedef struct _ya_token_keyword_t {  const char *keyword;  unsigned int length;  const token_t token;} token_keyword_t;/* list of keywords */static const token_keyword_t keywords[] = {  {"for", 3, TK_FOR},};/* peek next character */void lex_next(lex_status_t *lex) {  lex->current = *++lex->stream;}/* peek n characters */void lex_nextn(lex_status_t *lex, int len) {  lex->stream += len;  lex->current = *lex->stream;}/* match keywords */token_t lex_keyword(lex_status_t *lex) {  unsigned int i;  for( i = 0 ; i < (sizeof(keywords) / sizeof(*keywords)) ; i++ ) {    if( strncmp(lex->stream, keywords[i].keyword, keywords[i].length) == 0 ) {      lex_nextn(lex, keywords[i].length);      return keywords[i].token;    }  }  return TK_ERROR;}/* lexer main function */token_t lex(lex_status_t *lex) {  token_t token;  for(;;) {    switch( lex->current ) {      /* skip new line, white spaces and tabs */      case '\n':      case '\r':      case '\t':      case ' ':        lex_next(lex);        break;      /* match =, == */      case '=':        lex_next(lex);        switch( lex->current ) {          case '=':            lex_next(lex);            return TK_EQ;        }        return TK_ASSIGN;      /* match ( */      case '(':        lex_next(lex);        return TK_PARENTHESESO;      /* match ) */      case ')':        lex_next(lex);        return TK_PARENTHESESC;      /* match { */      case '{':        lex_next(lex);        return TK_BRACESO;      /* match } */      case '}':        lex_next(lex);        return TK_BRACESC;      /* match ; */      case ';':        lex_next(lex);        return TK_SEMICOLON;      /* match integer */      case '0': case '1': case '2': case '3':      case '4': case '5': case '6': case '7':      case '8': case '9':        do {          lex_next(lex);        } while(isdigit(lex->current));        return TK_NUMBER;      /* match end of file */      case '\0':        return TK_EOF;      default:        /* keyword? */        if( (token = lex_keyword(lex)) != TK_ERROR ) {          return token;        }        /* identifier? */        else if( isalpha(lex->current) || (lex->current == '_') ) {          do {            lex_next(lex);          } while( isalpha(lex->current) || (lex->current == '_') );          return TK_IDENTIFIER;        }        /* something unsupported */        else {          fprintf(stderr, "Unknown character %c\n", lex->current);          exit(0);        }    }  }  return TK_ERROR;}int main(int argc, char **argv) {  /* testcase */  const char *s =    "name = 1234;   \n"    "for( name ) {  \n"    "    name = 0;  \n"    "}       $_$    \n" /* bad character */    ;  lex_status_t state;  token_t token;  state.stream  = s; /* points to first string s */  state.current = *s; /* current -> first character */  do {    /* peek token */    token = lex(&state);    switch( token ) {      case TK_FOR           : puts("for");        break;      case TK_IDENTIFIER    : puts("identifier"); break;      case TK_NUMBER        : puts("number");     break;      case TK_EQ            : puts("==");         break;      case TK_ASSIGN        : puts("=");          break;      case TK_PARENTHESESO  : puts("(");          break;      case TK_PARENTHESESC  : puts(")");          break;      case TK_BRACESO       : puts("{");          break;      case TK_BRACESC       : puts("}");          break;      case TK_SEMICOLON     : puts(";");          break;      case TK_EOF           : puts("EOF");        break;      case TK_ERROR         : puts("TK_ERROR");   break;    }  } while( token != TK_EOF );  return 0;}

نتيجة التجربة:

name = 1234;   for( name ) {      name = 0;  }       $_$   

سيطبع:

> lexer.exeidentifier=number;for(identifier){identifier=number;}Unknown character $>
تم تعديل بواسطه Mr.B
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلا بك أخي الكريم

 يمنع طلب الاكواد الجاهزة

هل لديك رد سريع ؟

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

اهلا فيك مصطفى

 ممكن تعطيني رابط للاكواد

-1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
اريد اكتب برنامج بالملفات او بلغة ++c يدخل من قبل المستخدم ال lexan ويطبع ال token حقه , مثل for يطبع مقابله (keyword ) ,والمتغيرات (identifire),والعمليات الحسابيه مثل (=) يطبع (equal ) , وبقية الرموز

لو قمت بكتابة البرنامج بشكل يديوى لتحليل الـ tokens الخاصة بلغة c/cpp سيأخذ منك حوالي 1000 سطر و هذا مع عدم إضافة كود الطباعة.

 

توجد ادوات جاهزه لتوليد مثل هذا الكود مثل Flex و ANTLR و لكني لا استخدمهم كثيرا.

 

تحليل الـ tokens عملية يسيره فقط قم بقراءة الفصل الثاني Lexical conventions الموجود بتوثيق اى من اللغتين لتحليل عناصرها.

 

ملحوظه: سؤالك يشبة أول تمرين بكورس cppgm

 

 

و الله ولي التوفيق

تم تعديل بواسطه C++er
-1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .