Лексический анализатор

A) Грамматика лексических единиц и структура лексем

Множественные терминальные символы:

_CHAR_::={A..Z,a..z}

_DIGIT_::={0..9}

_RAZD_::= ‘{‘ , ‘}’ ,’ ‘, ‘(‘ , ‘ )’, ‘;’ , ‘ , ‘ , ‘ . ‘

_OP_::= ‘ * ‘ , ‘ + ‘ , ‘ < ’ , ‘ > ‘ , ‘ = ‘

Правила, описывающие лексические единицы идентификаторов ,служебных слов:

<IDENTIFICATOR>::=_CHAR_<CONT >

<CONT >::=_DIGIT_<CONT>

<CONT >::=_CHAR_<CONT>

<CONT >::=’(‘ <KEY>

<CONT >::=$

<KEY>::=’)’ | $

Правила, описывающие лексические единицы чисел:

<NUMBER>::=_DIGIT_<CONT_NUMBER>

<CONT_NUMBER>::=$ | <NUMBER>

< CONT_NUMBER>::=.< CONT_NUMBER _F>

< CONT_NUMBER _F>::=_DIGIT_< CONT_NUMBER _F>

< CONT_NUMBER _F>::=$

Правила, описывающие лексические единицы разделителя:

<R>::= _RAZD_<CONT_R>

<CONT_R>::= $

Правила, описывающие лексические единицы ‘операций’:

<OP>::=_OP_<CONT_OP>

<CONT_OP>::= <OP> | $

B) Матрица переходов лексического анализатора

/*_I_*/ /*_NbrI_*/ /*_NbrF_*/ /*_Id_*/ /*_Key_*/ /*_Op_*/

/*Digt*/ {BeginNbr,ProcessNbr ,ProcessNbr ,ProcessId ,EndKey ,EndOp },

/*Char*/ {BeginId ,Error ,Error ,ProcessId ,EndKey ,EndOp },

/*Op*/ {BeginOp ,EndNbr ,EndNbrF ,EndId ,Error ,ProcessOp },

/*{*/ {EndRazd ,Error ,Error ,Error ,Error ,Error },

/*}*/ {EndRazd ,Error ,Error ,Error ,Error ,Error },

/*(*/ {EndRazd ,Error ,Error ,ProcessKey,EndKey ,EndOp },

/*)*/ {EndRazd ,EndNbr ,EndNbrF ,EndId ,EndKey ,Error },

/*;*/ {EndRazd ,EndNbr ,EndNbrF ,EndId ,Error ,Error },

/* */ {EndRazd ,EndNbr ,EndNbrF ,EndId ,EndKey ,EndOp },

/*.*/ {Error ,ProcessNbrF,Error ,Error ,Error ,Error },

/*,*/ {EndRazd ,Error ,Error ,EndId ,Error ,Error }

Диаграмма состояний:

c) Структуры данных и символы действия лексического анализатора

Семантика лексического анализатора: заключается в том, что на вход лексического анализатора подается текст программы(цепочка символов) и на выходе мы получаем лексемы. Лексема должна быть представлена в следующей форме: класс, указатель на символьное представление. Класс-группа, к которой относится данная лексема -идентификатор, служебное слово, разделитель, операция, число (целочисленная константа , дробная константа). Указатель на символьное представление, например, может хранить номер в таблице символов. Лексический анализатор должен строить таблицу символьных представлений, таблицу идентификаторов.Для контроля за правильностью служебных слов можно создать таблицу допустимых служебных слов. И при обнаружении какого-то служебного слова в исходном тексте программы нужно проверить, а допустим ли такое слово.

class Lex: public Sortable

{

public:

Lex() {type=0;ptr.idx=0L;};

Lex(int t,int idx){type=t;ptr.idx=idx;};

Lex(int t,void *p ){type=t;ptr.ptr=p;};

Lex(Object &s)

{Lex::Lex((Lex&)s);}

Lex(const Lex& l)

{ if(this!=&l)

{

type=l.type;

ptr.idx=l.ptr.idx;

}

}

virtual classType isA() const { return 0xFF; }

virtual char *nameOf() const { return "Lexem"; }

virtual int isEqual( const Object& O) const

{return (type==((Lex&)O).type)&&(ptr.ptr==((Lex&)O).ptr.ptr);}

virtual int isLessThan( const Object& ) const {return 1;};

virtual hashValueType hashValue() const { return 0; }

virtual void printOn( ostream& out) const{output(out);}

int operator==(Lex &l)

{

return (type==l.type)&&(ptr.idx==l.ptr.idx);

}

void output(ostream &) const;

static void (*Table[11][6])();

static char* Errors[11][6];

static int classify(char);

private:

int type;

union

{ int idx;

void *ptr;

}ptr;

// Символы действия:

static void BeginNbr(); // начать обработку числовой константы

static void BeginId(); // начать обработку идентификатора

static void BeginOp(); // начать обработку операции

static void BeginRazd(); // начать обработку разделителя

static void ProcessNbr(); // обрабатывать целую константу

static void ProcessNbrF();// обрабатывать дробную константу

static void ProcessKey(); // обрабатывать служебное слово

static void ProcessId(); // обрабатывать идентификатор

static void ProcessOp(); // обрабатывать операцию

static void EndNbr(); // создать лексему - целую константу

static void EndNbrF(); // создать лексему - дробную константу

static void EndId(); // создать лексему - идентификатор

static void EndOp(); // создать лексему - операцию

static void EndKey(); // создать лексему - служебное слово

static void EndRazd(); // создать лексему - разделитель

static void Error();

static char* LexName[];

static char* RazdName[];

static char* KeyWord[];

static char* Op[];

static int nKeyWord;

static int nOp;

};

Соседние файлы в папке ARVIN
  • #
    01.05.20141.09 Mб8KURS-ARV.DOC
  • #
    01.05.2014776.53 Кб5TRY.BMP
  • #
    01.05.20142.16 Кб4ZZZ.BAK
  • #
    01.05.20141.37 Кб4ZZZ.GRM
  • #
    01.05.201411.11 Кб5ZZZ.TFN
  • #
    01.05.20142.16 Кб4ZZZ.TGR