Форум программистов, компьютерный форум CyberForum.ru

Множественные переопределения сбивающие компилятор столку - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Линейный однонаправленный список http://www.cyberforum.ru/cpp-beginners/thread1112241.html
Добрый вечер! Задача: L – линейный однонаправленный список Проверить, упорядочены ли элементы списка по алфавиту. Подскажите как сделать список классом? (без использования структур)
C++ Вертикальный скролл Здравствуйте! Не могу разобраться с вертикальным скроллом. Скиньте, пожалуйста, пример с рабочим вертикальным(ли горизонтальным) скроллом. (желательно WinAPI). http://www.cyberforum.ru/cpp-beginners/thread1112231.html
C++ Нужно написать рекурсивную функцию, которая определит - является ли симметричной часть строки от n, до z
Нужно написать рекурсивную функцию, которая определит - является ли симметричной часть строки от n, до z. Выдает ошибку: #include <iostream> bool simetrija(int start, int end, int *p); using namespace std; int main () { int mas={1,2,3,4,5,5,4,3,2,1}, n, z; cout<<"\ns kakogo chisla nachinat':"; cin>>n;
C++ Есть ли ошибки
В чем ошибка ? Все ли я правильно сделал? #include <new> #include <cstring> #include <iostream> using namespace std; // начало объявления класса enum color {red, gren, blue}; class monstr // имя самого класса
C++ Вывести русский текст http://www.cyberforum.ru/cpp-beginners/thread1112197.html
Помогите пожалуйста, как вывести в консоль не просто русский текст, а именно вывести текст из переменной?
C++ VS 12 ограничение на создание потоков Использую реализацию OpenMP для распараллеливания вычислений. Почему то больше 64 потоков не создает. 2х ядерный процессор, 3гб оперативки, но ни в какую не хочет создавать 100,200,300 потоков? подскажите, может в настройках что поменять надо или какие библиотеку подключить? просто это точно дело не в OpenMP так как видел примеры реализации с большим кол-вом потоков. Что это может быть за... подробнее

Показать сообщение отдельно
Xipxop
 Аватар для Xipxop
481 / 9 / 2
Регистрация: 28.12.2011
Сообщений: 150
05.03.2014, 21:09     Множественные переопределения сбивающие компилятор столку
Добрый вечер!
Пытаясь много раз сделать свой небольшой интерпретатор придуманного или с-подобного языка, я множество раз падал в ямы из которых вылезал, попадав в ямы поглубже... Не кидайте тапками говоря: нафига пирачишь, не твой код и не лезь туда... сам сделай..., я хочу понять как это сделано пытавшись все разобраться на практике меняя код, с целью понятия как он работает.(теория не помогла)

Скачав проект под названием Little C (а именно 3 .cpp файла, которые не связаны с собой никак,(компилировались make консольными командами)), и объеденив их в 1 проект(Все заголовки,структуры,енимы и глобалки в отдельные файлы) получил уйму ошибок. Долго расправлявшись с ошибками, расставив все по правилам .h файлов.(нельзя там создвать переменые и тд), пришел к ступору, а именно к ступору компилятора, который не жаловался ни на что!Но не собирался компилить это.

Суть проблемы или мои догадки: Проблема в неправильном разделении структур и их переменных.(интернет не дал дельных или рабочих разяснений по этому поводу)

вот сами файлы:
header.h
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
#pragma once
 
#include <stdio.h>
#include <setjmp.h>
#include <math.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
 
#define NUM_FUNC        100
#define NUM_GLOBAL_VARS 100
#define NUM_LOCAL_VARS  200
#define NUM_BLOCK       100
#define ID_LEN          31
#define FUNC_CALLS      31
#define NUM_PARAMS      31
#define PROG_SIZE       10000
#define LOOP_NEST       31
 
 
enum tok_types {DELIMITER, IDENTIFIER, NUMBER, KEYWORD,
                TEMP, STRING, BLOCK};
 
/* сюда можно добавить дополнительные лексемы
   зарезервированных слов */
enum tokens {ARG, CHAR, INT, IF, ELSE, FOR, DO, WHILE,
             SWITCH, RETURN, EOL, FINISHED, END};
 
/* сюда можно добавить дополнительные двухсимвольные операторы,
   например, -> */
enum double_ops {LT=1, LE, GT, GE, EQ, NE};
 
/* Эти константы используются для вызова функции sntx_err()
   в случае синтаксической ошибки. При необходимости список
   констант можно расширить.
   ВНИМАНИЕ: константа SYNTAX используется тогда, когда
   интерпритатор не может квалифицировать ошибку.
*/
enum error_msg
     {SYNTAX, UNBAL_PARENS, NO_EXP, EQUALS_EXPECTED,
      NOT_VAR, PARAM_ERR, SEMI_EXPECTED,
      UNBAL_BRACES, FUNC_UNDEF, TYPE_EXPECTED,
      NEST_FUNC, RET_NOCALL, PAREN_EXPECTED,
      WHILE_EXPECTED, QUOTE_EXPECTED, NOT_TEMP,
      TOO_MANY_LVARS, DIV_BY_ZERO};
 
//-------------------------------------------------------------------------------------------
int print();
void prescan();
void decl_global(), call(), putback();
void decl_local(), local_push(struct var_type i);
void eval_exp(int *value), sntx_err(int error);
void exec_if(), find_eob(), exec_for();
void get_params(), get_args();
void exec_while(), func_push(int i), exec_do();
void assign_var(char *var_name, int value);
int load_program(char *p, char *fname), find_var(char *s);
void interp_block(), func_ret();
int func_pop(), is_var(char *s), get_token();
char *find_func(const char *name);
 
extern char *prog;  /* текущее положение в исходном тексте программы */
extern char *p_buf;  /* указатель на начало буфера программы */
extern jmp_buf e_buf; /* содержит данные для longjmp() */
extern char token[80]; /* содержит строковое представление лексемы */
extern char token_type; /* содержит тип лексемы */
extern char tok; /* содержит внутренне представление лексемы */
extern int functos;  /* индекс вершины стека вызова функции */
extern int func_index; /* индекс в таблице функций */
extern int gvar_index; /* индекс в таблице глобальных переменных */
extern int lvartos; /* индекс в стеке локальных переменных */
extern int call_stack[NUM_FUNC];
 
int call_getche(), call_putch();
int call_puts(), getnum();
 
extern int ret_value; /* возвращаемое значение функции */
 
void eval_exp0(int *value);
void eval_exp(int *value);
void eval_exp1(int *value);
void eval_exp2(int *value);
void eval_exp3(int *value);
void eval_exp4(int *value);
void eval_exp5(int *value);
void atom(int *value);
void sntx_err(int error), putback();
void assign_var(char *var_name, int value);
int isdelim(char c), look_up(char *s), iswhite(char c);
int find_var(char *s), get_token();
int internal_func(char *s);
int is_var(char *s);
void call();
 
int call_getche();
int call_putch();
int get_token();
void sntx_err(int error), eval_exp(int *result);
void putback();
int getnum();
 
//--------------------------------------------------------------------------------
extern struct var_type global_vars[NUM_GLOBAL_VARS];
extern struct var_type local_var_stack[NUM_LOCAL_VARS];
extern struct func_type func_table[NUM_FUNC];

stucturs.h
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
#pragma once
 
#include "header.h"
 
/* Массив этих структур содержит информацию
   о глобальных переменных.
*/
struct var_type {
  char var_name[ID_LEN];
  int v_type;
  int value;
} global_vars[NUM_GLOBAL_VARS], local_var_stack[NUM_LOCAL_VARS];
 
struct func_type {
  char func_name[ID_LEN];
  int ret_type;
  char *loc;  /* адрес точки входа в файл */
} func_table[NUM_FUNC];
 
struct commands { /* таблица зарезервированных слов */
  const char command[20];
  char tok;
} table[] = { /* В эту таблицу */
  {"if", IF}, /* команды должны быть введены на нижнем регистре. */
  {"else", ELSE},
  {"for", FOR},
  {"do", DO},
  {"while", WHILE},
  {"char", CHAR},
  {"int", INT},
  {"return", RETURN},
  {"end", END},
  {"", END}  /* конец таблицы */
};
 
struct intern_func_type {
  const char *f_name; /* имя функции */
  int (*p)();   /* указатель на функцию */
} intern_func[] = {
  {"getche", call_getche},
  {"putch", call_putch},
  {"puts", call_puts},
  {"print", print},
  {"getnum", getnum},
  {"", 0}  /* этот список заканчивается нулем */
};

globals.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "header.h"
#include "stucturs.h"
 
 
//----------------------------------------------------------------------------
///var_type global_vars[NUM_GLOBAL_VARS];
///var_type local_var_stack[NUM_LOCAL_VARS];
///func_type func_table[NUM_FUNC];
//----------------------------------------------------------------------------
char *prog;    /* текущая позиция в исходном тексте программы */
char *p_buf;   /* указывает на начало буфера программы */
jmp_buf e_buf; /* содержит информацию для longjmp() */
int call_stack[NUM_FUNC];
 
char token[80];
char token_type, tok;
 
int functos;  /* индекс вершины стека вызова функции */
int func_index; /* индекс в таблице функций */
int gvar_index; /* индекс в таблице глобальных переменных */
int lvartos; /* индекс в стеке локальных переменных */
 
int ret_value; /* возвращаемое значение функции */

main.cpp
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
/* Интерпритатор языка Little C. */
 
#include "header.h"
#include "stucturs.h"
 
 
//extern struct var_type global_vars[NUM_GLOBAL_VARS];
 
int main(int argc, char *argv[])
{
  if(argc != 2) {
    printf("Применение: littlec <имя_файла>\n");
    exit(1);
  }
 
  /* выделение памяти для программы */
  if((p_buf = (char *) malloc(PROG_SIZE))==NULL) {
    printf("Выделить память не удалось");
    exit(1);
  }
 
  /* загрузка программы для выполнения */
  if(!load_program(p_buf, argv[1])) exit(1);
  if(setjmp(e_buf)) exit(1); /* инициализация буфера long jump */
 
  gvar_index = 0;  /* инициализация индекса глобальных переменных */
 
  /* установка указателя программы на начало буфера программы */
  prog = p_buf;
  prescan(); /* определение адресов всех функций
                и глобальных переменных программы */
 
  lvartos = 0;     /* инициализация индекса стека локальных переменных */
  functos = 0;     /* инициализация индекса стека вызова (CALL) */
 
  /* первой вызывается main() */
  prog = find_func("main"); /* поиск точки входа программы */
 
  if(!prog) { /* функция main() неправильна или отсутствует */
    printf("main() не найдена.\n");
    exit(1);
  }
 
  prog--; /* возврат к открывающейся скобке ( */
  strcpy(token, "main");
  call(); /* начало интерпритации main() */
 
  return 0;
}
 
/* Интерпритация одного оператора или блока. Когда
   interp_block() возвращает управление после первого
   вызова, в main() встретилась последняя
   закрывающаяся фигурная скобка или оператор return.
*/
void interp_block()
{
  int value;
  char block = 0;
 
  do {
    token_type = get_token();
 
    /* При интерпритации одного операторавозврат
       после первой точки с запятой.
    */
 
    /* определение типа лексемы */
    if(token_type == IDENTIFIER) {
      /* Это не зарегестрированное слово,
         обрабатывается выражение. */
      putback();  /* возврат лексемыво входной поток
        для дальнейшей обработки функцией eval_exp() */
      eval_exp(&value);  /* обработка выражения */
      if(*token!=';') sntx_err(SEMI_EXPECTED);
    }
    else if(token_type==BLOCK) {
      /* если это граничитель блока */
      if(*token == '{') /* блок */
        block = 1; /* интерпритация блока, а не оператора */
      else return; /* это }, возврат */
    }
    else /* зарезервированное слово */
      switch(tok) {
        case CHAR:
        case INT:     /* объявление локальной переменной */
          putback();
          decl_local();
          break;
        case RETURN:  /* возврат из вызова функции */
          func_ret();
          return;
        case IF:      /* обработка оператора if */
          exec_if();
          break;
        case ELSE:    /* обработка оператора else */
          find_eob(); /* поиск конца блока else
                         и продолжение выполнения */
          break;
        case WHILE:   /* обработка цикла while */
          exec_while();
          break;
        case DO:      /* обработка цикла do-while */
          exec_do();
          break;
        case FOR:     /* обработка цикла for */
          exec_for();
          break;
        case END:
          exit(0);
      }
  } while (tok != FINISHED && block);
}
 
/* Загрузка программы. */
int load_program(char *p, char *fname)
{
  FILE *fp;
  int i=0;
 
  if((fp=fopen(fname, "rb"))==NULL) return 0;
 
  i = 0;
  do {
    *p = getc(fp);
    p++; i++;
  } while(!feof(fp) && i<PROG_SIZE);
 
  if(*(p-2) == 0x1a) *(p-2) = '\0'; /* программа кончается
                                       нулевым символом */
  else *(p-1) = '\0';
  fclose(fp);
  return 1;
}
 
/* Найти адреса всех функций в программе
   и запомнить глобальные переменные. */
void prescan()
{
  char *p, *tp;
  char temp[32];
  int datatype;
  int brace = 0;  /* Если brace = 0, то текущая
                     позиция указателя программы находится
                     в не какой-либо функции. */
 
  p = prog;
  func_index = 0;
  do {
    while(brace) {  /* обход кода функции */
      get_token();
      if(*token == '{') brace++;
      if(*token == '}') brace--;
    }
 
    tp = prog; /* запоминание текущей позиции */
    get_token();
    /* тип глобальной переменной или возвращаемого значения функции */
    if(tok==CHAR || tok==INT) {
      datatype = tok; /* запоминание типа данных */
      get_token();
      if(token_type == IDENTIFIER) {
        strcpy(temp, token);
        get_token();
        if(*token != '(') { /* это должна быть глобальная переменная */
          prog = tp; /* возврат в начало объявления */
          decl_global();
        }
        else if(*token == '(') {  /* это должна быть функция */
          func_table[func_index].loc = prog;
          func_table[func_index].ret_type = datatype;
          strcpy(func_table[func_index].func_name, temp);
          func_index++;
          while(*prog != ')') prog++;
          prog++;
          /* сейчас prog указывает на открывающуюся
             фигурную скобку функции */
        }
        else putback();
      }
    }
    else if(*token == '{') brace++;
  } while(tok != FINISHED);
  prog = p;
}
 
/* Возврат адреса точки входа данной функции.
   Возврат NULL, если не надена.
*/
char *find_func(const char *name)
{
  register int i;
 
  for(i=0; i < func_index; i++)
    if(!strcmp(name, func_table[i].func_name))
      return func_table[i].loc;
 
  return NULL;
 }
 
/* Объявление глобальной переменной. */
void decl_global()
{
  int vartype;
 
  get_token();  /* определение типа */
 
  vartype = tok; /* запоминание типа переменной */
 
  do { /* обработка списка */
    global_vars[gvar_index].v_type = vartype;
    global_vars[gvar_index].value = 0;  /* инициализация нулем */
    get_token();  /* определение имени */
    strcpy(global_vars[gvar_index].var_name, token);
    get_token();
    gvar_index++;
  } while(*token == ',');
  if(*token != ';') sntx_err(SEMI_EXPECTED);
}
 
/* Объявление локальной переменной. */
void decl_local()
{
  struct var_type i;
 
  get_token();  /* определение типа */
 
  i.v_type = tok;
  i.value = 0;  /* инициализация нулем */
 
  do { /* обработка списка */
    get_token(); /* определение типа пременной */
    strcpy(i.var_name, token);
    local_push(i);
    get_token();
  } while(*token == ',');
  if(*token != ';') sntx_err(SEMI_EXPECTED);
}
 
/* Вызов функции. */
void call()
{
  char *loc, *temp;
  int lvartemp;
 
  loc = find_func(token); /* найти точку входа функции */
  if(loc == NULL)
    sntx_err(FUNC_UNDEF); /* функция не определена */
  else {
    lvartemp = lvartos;  /* запоминание индекса стека
                            локальных переменных */
    get_args();  /* получение аргумента функции */
    temp = prog; /* запоминание адреса возврата */
    func_push(lvartemp);  /* запоминание индекса стека
                             локальных переменных */
    prog = loc;  /* переустановка prog в начало функции */
    get_params(); /* загрузка параметров функции
                     значениями аргументов */
    interp_block(); /* интерпретация функции */
    prog = temp; /* восстановление prog */
    lvartos = func_pop(); /* восстановление стека
                             локальных переменных */
  }
}
 
/* Заталкивание аргументов функций в стек
   локальных переменных. */
void get_args()
{
  int value, count, temp[NUM_PARAMS];
  struct var_type i;
 
  count = 0;
  get_token();
  if(*token != '(') sntx_err(PAREN_EXPECTED);
 
  /* обработка списка значений */
  do {
    eval_exp(&value);
    temp[count] = value;  /* временное запоминание */
    get_token();
    count++;
  }while(*token == ',');
  count--;
  /* затолкнуть в local_var_stack в обратном порядке */
  for(; count>=0; count--) {
    i.value = temp[count];
    i.v_type = ARG;
    local_push(i);
  }
}
 
/* Получение параметров функции. */
void get_params()
{
  struct var_type *p;
  int i;
 
  i = lvartos-1;
  do { /* обработка списка параметров */
    get_token();
    p = &local_var_stack[i];
    if(*token != ')' ) {
      if(tok != INT && tok != CHAR)
        sntx_err(TYPE_EXPECTED);
 
      p->v_type = token_type;
      get_token();
 
      /* связывание имени пераметров с аргументом,
         уже находящимся в стеке локальных переменных */
      strcpy(p->var_name, token);
      get_token();
      i--;
    }
    else break;
  } while(*token == ',');
  if(*token != ')') sntx_err(PAREN_EXPECTED);
}
 
/* Возврат из функции. */
void func_ret()
{
  int value;
 
  value = 0;
  /* получение возвращаемого значения, если оно есть */
  eval_exp(&value);
 
  ret_value = value;
}
 
/* Затолкнуть локальную переменную. */
void local_push(struct var_type i)
{
  if(lvartos > NUM_LOCAL_VARS)
    sntx_err(TOO_MANY_LVARS);
 
  local_var_stack[lvartos] = i;
  lvartos++;
}
 
/* Выталкивание индекса в стеке локальных переменных. */
int func_pop()
{
  functos--;
  if(functos < 0) sntx_err(RET_NOCALL);
  return call_stack[functos];
}
 
/* Запись индекса в стек локальных переменных. */
void func_push(int i)
{
  if(functos>NUM_FUNC)
   sntx_err(NEST_FUNC);
  call_stack[functos] = i;
  functos++;
}
 
/* Присваивание переменной значения. */
void assign_var(char *var_name, int value)
{
  register int i;
 
  /* проверка наличия локальной переменной */
  for(i=lvartos-1; i >= call_stack[functos-1]; i--)  {
    if(!strcmp(local_var_stack[i].var_name, var_name)) {
      local_var_stack[i].value = value;
      return;
    }
  }
  if(i < call_stack[functos-1])
  /* если переменная нелокальная,
     ищем ее в таблице глобальных переменных */
    for(i=0; i < NUM_GLOBAL_VARS; i++)
      if(!strcmp(global_vars[i].var_name, var_name)) {
        global_vars[i].value = value;
        return;
      }
  sntx_err(NOT_VAR); /* переменная не найдена */
}
 
/* Получение значения переменной. */
int find_var(char *s)
{
  register int i;
 
  /* проверка наличия переменной */
  for(i=lvartos-1; i >= call_stack[functos-1]; i--)
    if(!strcmp(local_var_stack[i].var_name, token))
      return local_var_stack[i].value;
 
  /* в противном случае проверим,
     может быть это глобальная переменная */
  for(i=0; i < NUM_GLOBAL_VARS; i++)
    if(!strcmp(global_vars[i].var_name, s))
      return global_vars[i].value;
 
  sntx_err(NOT_VAR); /* переменная не найдена */
  return -1;
}
 
/* Если индентификатор является переменной, то
   возвращается 1, иначе 0.
*/
int is_var(char *s)
{
  register int i;
 
  /* это локальная переменная ? */
  for(i=lvartos-1; i >= call_stack[functos-1]; i--)
    if(!strcmp(local_var_stack[i].var_name, token))
      return 1;
 
  /* если нет - поиск среди глобальных переменных */
  for(i=0; i < NUM_GLOBAL_VARS; i++)
    if(!strcmp(global_vars[i].var_name, s))
      return 1;
 
  return 0;
}
 
/* Выполнение оператора if. */
void exec_if()
{
  int cond;
 
  eval_exp(&cond); /* вычисление if-выражения */
 
  if(cond) { /* истина - интерпретация if-предложения */
    interp_block();
  }
  else { /* в противном случае пропуск if-предложения
            и выполнение else-предложения, если оно есть */
    find_eob(); /* поиск конца блока */
    get_token();
 
    if(tok != ELSE) {
      putback();  /* восстановление лексемы,
                     если else-предложение отсутсвует */
      return;
    }
    interp_block();
  }
}
 
/* Выполнение цикла while. */
void exec_while()
{
  int cond;
  char *temp;
 
  putback();
  temp = prog;  /* запоминание адреса начала цикла while */
  get_token();
  eval_exp(&cond);  /* вычисление управляющего выражения */
  if(cond) interp_block();  /* если оно истинно, то выполнить
                               интерпритацию */
  else {  /* в противном случае цикл пропускается */
    find_eob();
    return;
  }
  prog = temp;  /* возврат к началу цикла */
}
 
/* Выполнение цикла do. */
void exec_do()
{
  int cond;
  char *temp;
 
  putback();
  temp = prog;  /* запоминание адреса начала цикла */
 
  get_token(); /* найти начало цикла */
  interp_block(); /* интерпритация цикла */
  get_token();
  if(tok != WHILE) sntx_err(WHILE_EXPECTED);
  eval_exp(&cond); /* проверка условия цикла */
  if(cond) prog = temp; /* если условие истинно,
  то цикл выполняется, в противном случае происходит
  выход из цикла */
}
 
/* Поиск конца блока. */
void find_eob()
{
  int brace;
 
  get_token();
  brace = 1;
  do {
    get_token();
    if(*token == '{') brace++;
    else if(*token == '}') brace--;
  } while(brace);
}
 
/* Выполнение цикла for. */
void exec_for()
{
  int cond;
  char *temp, *temp2;
  int brace ;
 
  get_token();
  eval_exp(&cond);  /* инициализирующее выражение */
  if(*token != ';') sntx_err(SEMI_EXPECTED);
  prog++; /* пропуск ; */
  temp = prog;
  for(;;) {
    eval_exp(&cond);  /* проверка условия */
    if(*token != ';') sntx_err(SEMI_EXPECTED);
    prog++; /* пропуск ; */
    temp2 = prog;
 
    /* поиск начала тела цикла */
    brace = 1;
    while(brace) {
      get_token();
      if(*token == '(') brace++;
      if(*token == ')') brace--;
    }
 
    if(cond) interp_block();  /* если условие выполнено,
                                 то выполнить интерпритацию */
    else {  /* в противном случае обойти цикл */
      find_eob();
      return;
    }
    prog = temp2;
    eval_exp(&cond); /* вполнение инкремента */
    prog = temp;  /* возврат в начало цикла */
  }
}

parser.cpp
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
/* Рекурсивный нисходящий синтаксический анализатор
   целочисленных выражений, содержащих переменные
   и вызовы функций.
*/
#include "header.h"
#include "stucturs.h"
 
 
/* Точка входа в синтаксический анализатор выражений. */
void eval_exp(int *value)
{
  get_token();
  if(!*token) {
    sntx_err(NO_EXP);
    return;
  }
  if(*token == ';') {
    *value = 0; /* пустое выражение */
    return;
  }
  eval_exp0(value);
  putback(); /* возврат последней лексемы во входной поток */
}
 
/* Обработка выражения в присваивании */
void eval_exp0(int *value)
{
  char temp[ID_LEN];  /* содержит имя переменной,
                         которой присваивается значение */
  register int temp_tok;
 
  if(token_type == IDENTIFIER) {
    if(is_var(token)) {  /* если эта переменная,
       посмотреть, присваивается ли ей значение */
      strcpy(temp, token);
      temp_tok = token_type;
      get_token();
      if(*token == '=') {  /* это присваивание */
        get_token();
        eval_exp0(value);  /* вычислить присваемое значение */
        assign_var(temp, *value);  /* присвоить значение */
        return;
      }
      else {  /* не присваивание */
        putback();  /* востановление лексемы */
        strcpy(token, temp);
        token_type = temp_tok;
      }
    }
  }
  eval_exp1(value);
}
 
/* Обработка операций сравнения. */
void eval_exp1(int *value)
{
  int partial_value;
  register char op;
  char relops[7] = {
    LT, LE, GT, GE, EQ, NE, 0
  };
 
  eval_exp2(value);
  op = *token;
  if(strchr(relops, op)) {
    get_token();
    eval_exp2(&partial_value);
    switch(op) {  /* вычисление результата операции сравнения */
      case LT:
        *value = *value < partial_value;
        break;
      case LE:
        *value = *value <= partial_value;
        break;
      case GT:
        *value = *value > partial_value;
        break;
      case GE:
        *value = *value >= partial_value;
        break;
      case EQ:
        *value = *value == partial_value;
        break;
      case NE:
        *value = *value != partial_value;
        break;
    }
  }
}
 
/*  Суммирование или вычисление двух термов. */
void eval_exp2(int *value)
{
  register char  op;
  int partial_value;
 
  eval_exp3(value);
  while((op = *token) == '+' || op == '-') {
    get_token();
    eval_exp3(&partial_value);
    switch(op) { /* суммирование или вычитание */
      case '-':
        *value = *value - partial_value;
        break;
      case '+':
        *value = *value + partial_value;
        break;
    }
  }
}
 
/* Умножение или деление двух множителей. */
void eval_exp3(int *value)
{
  register char  op;
  int partial_value, t;
 
  eval_exp4(value);
  while((op = *token) == '*' || op == '/' || op == '%') {
    get_token();
    eval_exp4(&partial_value);
    switch(op) { /* умножение, деление или деление целых */
      case '*':
        *value = *value * partial_value;
        break;
      case '/':
        if(partial_value == 0) sntx_err(DIV_BY_ZERO);
        *value = (*value) / partial_value;
        break;
      case '%':
        t = (*value) / partial_value;
        *value = *value-(t * partial_value);
        break;
    }
  }
}
 
/* Унарный + или -. */
void eval_exp4(int *value)
{
  register char  op;
 
  op = '\0';
  if(*token == '+' || *token == '-') {
    op = *token;
    get_token();
  }
  eval_exp5(value);
  if(op)
    if(op == '-') *value = -(*value);
}
 
/* Обработка выражения в скобках. */
void eval_exp5(int *value)
{
  if((*token == '(')) {
    get_token();
    eval_exp0(value);   /* вычисление подвыражения */
    if(*token != ')') sntx_err(PAREN_EXPECTED);
    get_token();
  }
  else
    atom(value);
}
 
/* Получение значения числа, переменной или функции. */
void atom(int *value)
{
  int i;
 
  switch(token_type) {
  case IDENTIFIER:
    i = internal_func(token);
    if(i!= -1) {  /* вызов функции из "стандартной билиотеки" */
      *value = (*intern_func[i].p)();
    }
    else
    if(find_func(token)) { /* вызов функции,
                              определенной пользователем */
      call();
      *value = ret_value;
    }
    else *value = find_var(token); /* получение значения переменной */
    get_token();
    return;
  case NUMBER: /* числовая константа */
    *value = atoi(token);
    get_token();
    return;
  case DELIMITER: /* это символьная константа? */
    if(*token == '\'') {
      *value = *prog;
      prog++;
      if(*prog!='\'') sntx_err(QUOTE_EXPECTED);
      prog++;
      get_token();
      return ;
    }
    if(*token==')') return; /* обработка пустого выражения */
    else sntx_err(SYNTAX); /* синтаксическая ошибка */
  default:
    sntx_err(SYNTAX); /* синтаксическая ошибка */
  }
}
 
/* Вывод сообщения об ошибке. */
void sntx_err(int error)
{
  char *p, *temp;
  int linecount = 0;
  register int i;
 
  static const char *e[]= {
    "синтаксическая ошибка",
    "несбалансированные скобки",
    "выражение отсутствует",
    "ожидается знак равенства",
    "не переменная",
    "ошибка в параметре",
    "ожидается точка с запятой",
    "несбалансированные фигурные скобки",
    "функция не определена",
    "ожидается спецификатор типа",
    "слишком много вложенных вызовов функций",
    "оператор return вне функции",
    "ожидаются скобки",
    "ожидается while",
    "ожидается закрывающаяся кавычка",
    "не строка",
    "слишком много локальных переменных",
    "деление на нуль"
  };
  printf("\n%s", e[error]);
  p = p_buf;
  while(p != prog) {  /* поиск номера строки с ошибкой */
    p++;
    if(*p == '\r') {
      linecount++;
    }
  }
  printf(" in line %d\n", linecount);
 
  temp = p;
  for(i=0; i < 20 && p > p_buf && *p != '\n'; i++, p--);
  for(i=0; i < 30 && p <= temp; i++, p++) printf("%c", *p);
 
  longjmp(e_buf, 1); /* возврат в безопасную точку */
}
 
/* Считывание лексемы из входного потока. */
int get_token(void)
{
 
  register char *temp;
 
  token_type = 0; tok = 0;
 
  temp = token;
  *temp = '\0';
 
  /* пропуск пробелов, символов табуляции и пустой строки */
  while(iswhite(*prog) && *prog) ++prog;
 
  if(*prog == '\r') {
    ++prog;
    ++prog;
    /* пропуск пробелов */
    while(iswhite(*prog) && *prog) ++prog;
  }
 
  if(*prog == '\0') { /* конец файла */
    *token = '\0';
    tok = FINISHED;
    return (token_type = DELIMITER);
  }
 
  if(strchr("{}", *prog)) { /* ограничение блока */
    *temp = *prog;
    temp++;
    *temp = '\0';
    prog++;
    return (token_type = BLOCK);
  }
 
  /* поиск комментариев */
  if(*prog == '/')
    if(*(prog+1) == '*') { /* это комментарий */
      prog += 2;
      do { /* найти конец комментария */
        while(*prog != '*') prog++;
        prog++;
      } while (*prog != '/');
      prog++;
    }
 
  if(strchr("!<>=", *prog)) { /* возможно, это
                                       оператор сравнения */
    switch(*prog) {
      case '=': if(*(prog+1) == '=') {
          prog++; prog++;
          *temp = EQ;
          temp++; *temp = EQ; temp++;
          *temp = '\0';
       }
       break;
      case '!': if(*(prog+1) == '=') {
          prog++; prog++;
          *temp = NE;
          temp++; *temp = NE; temp++;
          *temp = '\0';
       }
       break;
      case '<': if(*(prog+1) == '=') {
          prog++; prog++;
          *temp = LE; temp++; *temp = LE;
       }
       else {
          prog++;
          *temp = LT;
       }
       temp++;
       *temp = '\0';
       break;
      case '>': if(*(prog+1) == '=') {
          prog++; prog++;
          *temp = GE; temp++; *temp = GE;
       }
       else {
         prog++;
         *temp = GT;
       }
       temp++;
       *temp = '\0';
       break;
    }
    if(*token) return(token_type = DELIMITER);
  }
 
  if(strchr("+-*^/%=;(),'", *prog)){ /* разделитель */
    *temp = *prog;
    prog++; /* продвижение на следующую позицию */
    temp++;
    *temp = '\0';
    return (token_type = DELIMITER);
  }
 
  if(*prog=='"') { /* строка в кавычках */
    prog++;
    while(*prog != '"'&& *prog != '\r') *temp++ = *prog++;
    if(*prog == '\r') sntx_err(SYNTAX);
    prog++; *temp = '\0';
    return (token_type = STRING);
  }
 
  if(isdigit(*prog)) { /* число */
    while(!isdelim(*prog)) *temp++ = *prog++;
    *temp = '\0';
    return (token_type = NUMBER);
  }
 
  if(isalpha(*prog)) { /* переменная или оператор */
    while(!isdelim(*prog)) *temp++ = *prog++;
    token_type = TEMP;
  }
 
  *temp = '\0';
 
  /* эта строка является оператором или переменной? */
  if(token_type==TEMP) {
    tok = look_up(token); /* преобразовать во внутренее представление */
    if(tok) token_type = KEYWORD; /* это зарезервированное слово */
    else token_type = IDENTIFIER;
  }
  return token_type;
}
 
/* Возврат лексемы во входной поток. */
void putback()
{
  char *t;
 
  t = token;
  for(; *t; t++) prog--;
}
 
/* Поиск внутреннего представления лексемы
   в таблице лексем.
*/
int look_up(char *s)
{
  register int i;
  char *p;
 
  /* преобразование в нижний регистр */
  p = s;
  while(*p) { *p = tolower(*p); p++; }
 
  /* есть ли лексемы в таблице? */
  for(i=0; *table[i].command; i++) {
    if(!strcmp(table[i].command, s)) return table[i].tok;
  }
  return 0; /* незнакомый оператор */
}
 
/* Возвращает идекс функции во внутренней
   библиотеке, или -1, если не найдена.
*/
int internal_func(char *s)
{
  int i;
 
  for(i=0; intern_func[i].f_name[0]; i++) {
    if(!strcmp(intern_func[i].f_name, s))  return i;
  }
  return -1;
}
 
/* Возвращает true (ИСТИНА), если с - разделитель. */
int isdelim(char c)
{
  if(strchr(" !;,+-<>'/*%^=()", c) || c == 9 ||
     c == '\r' || c == 0) return 1;
  return 0;
}
 
/* Возвращает 1, если с - пробел или табуляция. */
int iswhite(char c)
{
  if(c == ' ' || c == '\t') return 1;
  else return 0;
}

lclib.cpp
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
/****** Библиотека функций Little C *******/
 
/* Сюда можно добавлять новые функции. */
 
#include "header.h"
#include "stucturs.h"
 
 
 
int call_getche()
{
  char ch;
  ch = getchar();
  while(*prog!=')') prog++;
  prog++;   /* продвижение к концу строки */
  return ch;
}
 
/* Вывод символа на экран. */
int call_putch()
{
  int value;
 
  eval_exp(&value);
  printf("%c", value);
  return value;
}
 
/* Вызов функции puts(). */
int call_puts()
{
  get_token();
  if(*token!='(') sntx_err(PAREN_EXPECTED);
  get_token();
  if(token_type!=STRING) sntx_err(QUOTE_EXPECTED);
  puts(token);
  get_token();
  if(*token!=')') sntx_err(PAREN_EXPECTED);
 
  get_token();
  if(*token!=';') sntx_err(SEMI_EXPECTED);
  putback();
  return 0;
}
 
/* Встроенная функция консольного вывода. */
int print()
{
  int i;
 
  get_token();
  if(*token!='(')  sntx_err(PAREN_EXPECTED);
 
  get_token();
  if(token_type==STRING) { /* вывод строки */
    printf("%s ", token);
  }
  else {  /* вывод числа */
   putback();
   eval_exp(&i);
   printf("%d ", i);
  }
 
  get_token();
 
  if(*token!=')') sntx_err(PAREN_EXPECTED);
 
  get_token();
  if(*token!=';') sntx_err(SEMI_EXPECTED);
  putback();
  return 0;
}
 
/* Считывание целого числа с клавиатуры. */
int getnum()
{
  char s[80];
 
  gets(s);
  while(*prog != ')') prog++;
  prog++;  /* продвижение к концу строки */
  return atoi(s);
}


Другие компиляторы жаловались на бредовые ошибки, типа переменые структур объявлены много раз во всех cpp файлах...(хотя объявлены 1 раз в stucturs.h)
Прошу укажите на ошибку и вангуя проблему в структурах и их переменных: как ее решить? И где можно почитать полезной информации о таких заподлянках многофайловой структуры c++.
Заранее благодарю
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 14:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru