Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
Subotin
0 / 0 / 0
Регистрация: 16.11.2014
Сообщений: 13
1

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

07.02.2015, 16:50. Просмотров 455. Ответов 2
Метки нет (Все метки)

Здравствуйте уважаемые форумчане помогите пожалуйста! В книге K&R приводится пример небольшого лексического анализатора код которого мне вобщем понятен за исключением этого ungetch(c); return tokentype=NAME;
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#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;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.02.2015, 16:50
Ответы с готовыми решениями:

Лексический анализатор
Всем привет! Пишу интерпретатор, для начала нужно разобраться с лексическим...

Что делает эта строчка: ++x &amp;&amp; ++y || ++z; ?
Что делает эта строчка? ++x &amp;&amp; ++y || ++z;

K&R 2.2 Напишите цикл, не используя || и &&
эквивалентный этому циклу for (i = 0; i &lt; lim-1 &amp;&amp; (c=getchar()) != '\n' &amp;&amp; c...

В чем отличие & и && ?
В чем отличие &amp; и &amp;&amp; ? например if (px == x &amp;&amp; py == y) и if (px...

Матрица. Подсчитать количество строк, ВСЕ элементы которых >=6 && <=8
Дан табель отметок. Нужно посчитать количество хорошистов. (Отметки &gt;=6 &amp;&amp; &lt;=8)...

2
gazlan
3161 / 1920 / 312
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
07.02.2015, 18:18 2
Цитата Сообщение от Subotin Посмотреть сообщение
понятен за исключением этого
Лучше указывать номер строки кода.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
}
0
Evg
Эксперт CАвтор FAQ
19636 / 7328 / 551
Регистрация: 30.03.2009
Сообщений: 20,491
Записей в блоге: 30
08.02.2015, 11:21 3
А что конкретно непонятно?

ungetch как бы возвращает обратно во входной поток считанный из файла символ. Но символ пихается не в файл, и текущая позиция в файле не двигается (потому что файл может быть устройством ввода, где нет такого понятия), а коллекционируется в отдельном буфере. А в функции getch сначала проверяется этот самый буфер, если там есть символы, то предварительно вынимаются оттуда. Таким образом моделируется операция возврата прочитанного символа во входной поток, но при этом никаких дополнительных операций над потоком не делается

return tokentype=NAME; по сути выполняет пару действий: "tokentype=NAME; return tokentype;"
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.02.2015, 11:21

Переписать цикл без использования операторов && и ||
Нижеприведенный цикл нужно написать без использования операторов &amp;&amp; и || : ...

Каким можно заменить операцию &&
Приветствую #include&lt;stdio.h&gt; int main (void) { int a=5;b=60;c; c=a&amp;&amp;amp;b;...

Ошыбка в if(e==' ')&&(e<'a')&&(e>'z')
Задача: Нужно найти для заданого текста длину максимальной серии символов,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru