Лексический анализ. Изучение работы и методов построения лексического анализатора., страница 2

"if", "int", "main", "return", "struct", "void", "while"};

void mes()

{

msg.Insert("Ошибка в строке №", msg.Length() + 1);

msg.Insert(NumLine, msg.Length() + 1);

Application->MessageBoxA(msg.c_str(), "Ошибка на этапе лексического анализа", 0);

}

struct Common

{

char *info;

int n;

Common *left, *right;

};

void fill(char **arr, Common *tree)

{

if (tree != NULL)

{

arr[tree->n -1 ] = new char [strlen(tree->info)+1];

strcpy(arr[tree->n - 1], tree->info);

fill(arr, tree->left);

fill(arr, tree->right);

}

}

void out(char **arr, int count, Common *tree, TMemo *m)

{

int i;

arr = new char *[count]; fill(arr, tree);

des.Delete(1, des.Length());

for (i = 0; i < count; ++i)

{

des.Insert(i+1, des.Length()+1);

des.Insert("\t", des.Length()+1);

des.Insert(arr[i], des.Length()+1);

des.Insert("\r\n", des.Length()+1);

}

m->SetTextBuf(des.c_str());

}

void instext(int n, int k)

{

des.Insert("(", des.Length());

des.Insert(n, des.Length());

des.Insert("; ", des.Length());

des.Insert(k, des.Length());

des.Insert(")   ", des.Length());

}

void push(Common **tree, char *buffer, int &n)

{

++n;

(*tree) = new Common;

(*tree)->info = new char [strlen(buffer)+1];

strcpy((*tree)->info, buffer);

(*tree)->left = 0;

(*tree)->right = 0;

(*tree)->n = n;

instext(curlex, n);

}

void insert(Common **tree, char *b, int &n)

{

int t = strcmp((*tree)->info, b);

if (t == 0)

instext(curlex, (*tree)->n);

else if (t < 0)

{

if ((*tree)->left != NULL)

insert(&(*tree)->left, b, n);

else

push(&((*tree)->left), b, n);

}

else

{

if ((*tree)->right != NULL)

insert(&((*tree)->right), b, n);

else

push(&((*tree)->right), b, n);

}

}

int search(char *arr, char **source, int n)

{

int t, l = 0, r = n-1, c;

while (l <= r)

{

c = (l + r) / 2;

t = strcmp(arr, source[c]);

if (t == 0) return 1;

else if (t < 0) r = c-1;

else l = c + 1;

}

return 0;

}

int Separ(char c)

{

if (c >= 40 && c <= 47 || c >= 59 && c <= 62 || c == '{' || c == '}' || c == '!' || c == '%' || c == '&' ||  c == '[' || c == ']') return 1;

return 0;

}

int type(char c)

{

if (c >= 65 && c <= 90 || c >= 97 && c <= 122 || c == '_') return LETTER;

if (c == '"') return STR;

if (c == '\'') return SYMBOL;

if (c >= 48 && c <= 57) return DIGIT;

if (Separ(c)) return SEPARATOR;

if (c == ' ' || c == '\r') return SPACE;

if (c == '\0') return END;

if (c == '\n') return NEWLINE;

if (c == '^' || c == '@' || c == '#' || c == '~' || c == ':' || c == '?' || c == '№') return ADDITIONAL;

return -1;

}

void __fastcall TForm1::N2Click(TObject *Sender)

{

int N, i, t, j, state, id;

countKW = 0, countId = 0, countSep = 0, countSym = 0, countStr = 0, countDig = 0;

N = Form1->source->GetTextLen();

++N;

str = new char[N];

Form1->source->GetTextBuf(str, N);

Common *KeyWords=0, *Identificators=0, *Separators=0, *SymbolConst=0, *StringConst=0, *DigitConst=0;

des.Delete(1, des.Length());

des.Insert(" ", 1);

msg.Delete(1, msg.Length());

NumLine = 1;

for (i = 0; i < N-1;)

{

t = type(str[i]);

switch(t)

{

case SPACE:

++i;

break;

case NEWLINE:

++NumLine; ++i;

des.Insert("\r\n", des.Length());

break;

case END:

return;

case LETTER:

j = 1;

buffer[0] = str[i++];

state = 1;

id = 1;

curlex = LETTER;

while (id)

{

switch (state)

{

case 1:

t = type(str[i]);

if (t == LETTER || t == DIGIT)

buffer[j++] = str[i++];

else if (t == SEPARATOR || t == SPACE || t == NEWLINE)

state = 2;

else

{

mes(); return;

}

break;

case 2:

id = 0;

buffer[j] = 0;

if (search(buffer, AllKeyWords, 13))

{

if (countKW == 0)

push(&KeyWords, buffer, countKW);

else

insert(&KeyWords, buffer, countKW);

}

else

{

curlex += 10;

if (countId == 0)

push(&Identificators, buffer, countId);

else

insert(&Identificators, buffer, countId);

}

}

}

break;

case SYMBOL:

j = 0;

state = 1;

id = 1;

curlex = SYMBOL;

while (id)

{

switch (state)

{

case 1:

++i;

buffer[j++] = str[i];

if (str[i] == '\\')