Лексический анализатор из K&R - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте помогите пожалуйста! В книге K&R приводится пример небольшого лексического анализатора код которого мне вобщем понятен за исключением этого ungetch(c); return tokentype=NAME;
#include <stdio.h>
#include <string.h>
#include <ctype.h>
 
#define MAXTOKEN 100
#define BUFFSIZE 100
 
enum { NAME, PARENS, BRACKETS };
 
int gettoken();
int getch();
void dcl();
void dirdcl();
void ungetch(int);
 
int tokentype;
int bufp=0;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];
char buffer[BUFFSIZE];
 
main() {
   
  while(gettoken() != EOF) {
        strcpy(datatype, token); /*first arg of programm must be type(int,char or ...)*/
        out[0]='\0';
        dcl();
       if(tokentype!='\n')
          printf("syntax error.\n");
       printf("%s: %s %s\n", name, out, datatype);
       }
  return 0;
}
 
int gettoken() {
  int c, getch();
  void ungetch(int);
  char *p=token;
 
while((c=getch()) == ' ' || c == '\t')
             ;
  if(c == '(') {
       if((c=getch()) == ')') {
          strcpy(token, "()");
       return tokentype = PARENS;
  } else {
          ungetch(c);
         return tokentype=')';
     }
 } else if(c == '[') {
      for(*p++=c; (*p++=getch()) != ']';)
                   ;
              *p='\0';
         return tokentype=BRACKETS;
 } else if(isalpha(c)) {
      for(*p++=c; isalnum(c=getch());)
              *p++=c;
            *p='\0';
          ungetch(c);
     return tokentype=NAME;
 } else
     return tokentype=c;
}
 
void dcl() {
     int ns;
for(ns=0; gettoken() == '*';) 
       ns++;
    dirdcl();
 while(ns-- > 0)
   strcat(out, " pointer to");
}
 
void dirdcl() {
    int type;
if(tokentype == '(') {
   dcl();
    if(tokentype != ')')
        printf("error: missing ) \n");
 } else if(tokentype == NAME) 
     strcpy(name, token);
  else
     printf("error: expected name or ()\n");
 
while((type=gettoken()) == PARENS || type == BRACKETS) {
       if(type == PARENS)
          strcat(out, "function returning");
    else {
          strcat(out, "array");
          strcat(out, token);
          strcat(out, " of");
         }
    }
}          
 
int getch() {
    return (bufp > 0)? buffer[--bufp] : getchar();
}
 
void ungetch(int c) {
    if(bufp >= BUFFSIZE)
       printf("error: too much characters\n");
    else
       buffer[bufp++]=c;
}

Решение задачи: «Лексический анализатор из K&R»

textual
Листинг программы
if (isalpha(c))
{
   // Collect alphanum chars
   for (*p++ = c; isalnum(c = getch()); )
   {
      *p++ = c;
   }
 
   *p = 0;  // Ensure ASCIIZ
   
   ungetch(c); // Return last (Non alphanum) char to input stream
   
   return tokentype = NAME;   // Set token type as NAME
}

Объяснение кода листинга программы

В данном коде выполняется функция, которая является лексическим анализатором. Она предназначена для сбора имени (токена типа NAME) из входного потока символов.

  1. Проверка условия: Если текущий символ является буквой (isalpha), то начинается сбор имени.
  2. Сбор имени: Используется цикл, который продолжает собирать имя, пока не встретит не буквенно-цифровой символ (isalnum). Для каждого собранного символа выделяется память с помощью оператора new, и затем символ копируется в выделенную память.
  3. Очистка символа: После сбора имени, последний символ, который не является буквенно-цифровым, помещается обратно в поток с помощью функции ungetch.
  4. Завершение работы: Выделяемая память освобождается, а переменная tokentype устанавливается в значение NAME, указывая, что собранное имя. Список переменных и их значений:
  5. c - Текущий символ
  6. p - Указатель на память, выделенную для хранения имени
  7. tokentype - Тип токена, в данном случае NAME
  8. getch() - Функция, которая возвращает следующий символ из входного потока
  9. ungetch() - Функция, которая возвращает последний символ обратно в поток
  10. isalpha() - Функция, которая проверяет, является ли символ буквой
  11. isalnum() - Функция, которая проверяет, является ли символ буквой или цифрой
  12. new() - Функция, которая выделяет память для создания нового объекта
  13. delete() - Функция, которая освобождает память, выделенную для объекта
  14. NAME - Тип токена, указывающий на имя

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 3.667 из 5
Похожие ответы