Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
1

Парсер

14.01.2019, 20:22. Показов 1725. Ответов 15
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, уважаемые программисты!
в книге нашла код анализатора выражений, но не получается его скомпилировать. Не могу понять почему, так как выходят ошибки, типа
Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка LNK2001 эхЁрчЁх°хээ√щ тэх°эшщ ёшьтюы ""char * prog" (?prog@@3PEADEA)"

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
#include <iostream>
#include <cctype>
#include <cstdlib>
#include <cstring>
using namespace std;
 
// The Small Basic token types.
enum typesT { UNDEFTOK, OPERATOR, NUMBER, VARIABLE, COMMAND,
              STRING, QUOTE };
 
// The Small Basic command tokens.
enum SBtokensT { UNKNCOM, PRINT, INPUT, IF, THEN, FOR, NEXT, TO,
                 GOTO, GOSUB, RETURN, EOL, FINISHED, END };
 
/* These are the constants used to call serror() when
   a syntax error occurs.  Add more if you like.
   NOTE: SERROR is a generic error message used when
   nothing else seems appropriate. */
enum errorsT 
    { SERROR, PARENS, NOEXP, DIVZERO, EQUAL_EXP,
      NOT_VAR, LAB_TAB_FULL, DUP_LAB, UNDEF_LAB,
      THEN_EXP, TO_EXP, TOO_MNY_FOR, NEXT_WO_FOR,
      TOO_MNY_GOSUB, RET_WO_GOSUB, MISS_QUOTE };
 
enum double_ops { LE=1, GE, NE };
 
extern char *prog;  // points into the program 
extern char *p_buf; // points to start of program
 
extern int variables[26]; // variables 
 
extern struct commands { 
  char command[20];
  SBtokensT tok;
} table[];
 
extern char token[80]; // holds string representation of token 
extern typesT token_type; // contains type of token 
extern SBtokensT tok; // holds the internal representation of token 
 
void eval_exp(int &result);
void eval_exp1(int &result);
void eval_exp2(int &result);
void eval_exp3(int &result);
void eval_exp4(int &result);
void eval_exp5(int &result);
void eval_exp6(int &result);
void atom(int &result);
void putback();
void serror(errorsT error);
typesT get_token();
SBtokensT look_up(char *s);
bool isdelim(char c);
bool is_sp_tab(char c);
int find_var(char *s);
 
// Entry point into parser. 
void eval_exp(int &result)
{
  get_token(); 
  if(!*token) {
    serror(NOEXP); 
    return; 
  }
  eval_exp1(result); 
  putback(); // return last token read to input stream 
}
 
// Process relational operators. 
void eval_exp1(int &result)
{
  // Relational operators.
  char relops[] = {
    GE, NE, LE, '<', '>', '=', 0
  };
 
  int temp;
  register char op;
 
  eval_exp2(result);
  op = *token;
  if(strchr(relops, op)) {
    get_token();
    eval_exp1(temp);
    switch(op) { // perform the relational operation 
      case '<':
        result = result < temp;
        break;
      case LE:
        result = result <= temp;
        break;
      case '>':
        result = result > temp;
        break;
      case GE:
        result = result >= temp;
        break;
      case '=':
        result = result == temp;
        break;
      case NE:
        result = result != temp;
        break;
    }
  }
}
 
//  Add or subtract two terms. 
void eval_exp2(int &result)
{
  register char op; 
  int temp; 
 
  eval_exp3(result); 
  while((op = *token) == '+' || op == '-') {
    get_token(); 
    eval_exp3(temp); 
    switch(op) {
      case '-' :
        result = result - temp;
        break;
      case '+':
        result = result + temp;
        break;
    }
  }
}
 
// Multiply or divide two factors. 
void eval_exp3(int &result)
{
  register char op; 
  int temp; 
 
  eval_exp4(result); 
  while((op = *token) == '*' || op == '/') {
    get_token(); 
    eval_exp4(temp); 
    switch(op) {
      case '*' :
        result = result * temp;
        break;
      case '/':
        if(!temp) serror(DIVZERO); // division by zero attempted
        result = result / temp;
        break;
    }
  }
}
 
// Process integer exponent.
void eval_exp4(int &result)
{
  int temp, ex; 
  register int t;
 
  eval_exp5(result); 
  if(*token== '^') {
    get_token(); 
    eval_exp4(temp); 
    if(!temp) {
      result = 1;
      return;
    }
    ex = result;
    for(t=temp-1; t>0;  t--) result = result * ex;
  }
}
 
// Is a unary + or -. 
void eval_exp5(int &result)
{
  register char op; 
 
  op = 0; 
  if((token_type==OPERATOR) &&
      *token=='+' || *token=='-')
  {
    op = *token; 
    get_token(); 
  }
  eval_exp6(result); 
  if(op=='-') result = -result;
}
 
// Process parenthesized expression. 
void eval_exp6(int &result)
{
  if(*token == '(') {
    get_token(); 
    eval_exp2(result); 
    if(*token != ')')
      serror(PARENS); 
    get_token(); 
  }
  else
    atom(result); 
}
 
// Find value of number or variable. 
void atom(int &result)
{
  switch(token_type) {
    case VARIABLE:
      result = find_var(token); 
      get_token(); 
      return; 
    case NUMBER:
      result = atoi(token); 
      get_token();   
      return; 
    default:
      serror(SERROR); 
    }
}
 
// Find the value of a variable. 
int find_var(char *s)
{
  if(!isalpha(*s)){
    serror(NOT_VAR); // not a variable
    return 0; 
  }
  return variables[toupper(*token)-'A']; 
}
 
// Display an error message.
void serror(errorsT error)
{
  char *p, *temp;
  int linecount = 0;
  register int i;
 
  static const char *e[]= {   
    "Syntax error", 
    "Unbalanced parentheses", 
    "No expression present",
    "Division by zero",
    "Equal sign expected",
    "Not a variable",
    "Label table full",
    "Duplicate label",
    "Undefined label",
    "THEN expected",
    "TO expected",
    "Too many nested FOR loops",
    "NEXT without FOR",
    "Too many nested GOSUBs",
    "RETURN without GOSUB",
    "Double qoutes needed"
  }; 
  cout << e[error]; 
 
  p = p_buf;
  while(p != prog) {  // find line number of error 
    p++;
    if(*p == '\r') {
      linecount++;
    }
  }
  cout << " in line " << linecount << ".\n";
 
  temp = p;  // display line with error
  for(i=0; i<20 && p>p_buf && *p!='\n'; i++, p--);
  for(; p<=temp; p++) cout << *p;
    
  throw(1); // throw an exception
}
 
// Get a token. 
typesT get_token()
{
  register char *temp;
 
  token_type = UNDEFTOK; 
  tok = UNKNCOM;
  temp = token;
 
  if(*prog=='\0') { // end of file 
    *token = '\0';
    tok = FINISHED;
    return(token_type=OPERATOR);
  }
 
  while(is_sp_tab(*prog)) ++prog;  // skip over white space 
 
  if(*prog=='\r') { // crlf 
    ++prog; ++prog;
    tok = EOL; *token='\r';
    token[1]='\n'; token[2]=0;
    return (token_type = OPERATOR);
  }
 
  if(strchr("<>", *prog)) { // check for double op
    switch(*prog) {
      case '<':
        if(*(prog+1)=='>') {
          prog++; prog++;
          *temp = NE;
        }
        else if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = LE;
        }
        else {
          prog++;
          *temp = '<';
        }
        temp++;
        *temp = '\0';
        break;
      case '>':
        if(*(prog+1)=='=') {
          prog++; prog++;
          *temp = GE;
        }
        else {
          prog++;
          *temp = '>';
        }
        temp++;
        *temp = '\0';
        break;
    }
    return(token_type = OPERATOR);
  }
 
  if(strchr("+-*^/=;(),", *prog)){ // operator
    *temp = *prog;
    prog++; // advance to next position 
    temp++;
    *temp = '\0'; 
    return (token_type=OPERATOR);
  }
    
  if(*prog=='"') { // quoted string 
    prog++;
    while(*prog!='"'&& *prog!='\r') *temp++ = *prog++;
    if(*prog=='\r') serror(MISS_QUOTE);
    prog++; *temp = '\0';
    return(token_type=QUOTE);
  }
  
  if(isdigit(*prog)) { // number 
    while(!isdelim(*prog)) *temp++ = *prog++;
    *temp = '\0';
    return(token_type = NUMBER);
  }
 
  if(isalpha(*prog)) { // var or command 
    while(!isdelim(*prog)) *temp++ = *prog++;
    token_type = STRING;
  }
  
  *temp = '\0';
 
  // see if a string is a command or a variable 
  if(token_type==STRING) {
    tok = look_up(token); // convert to internal rep 
    if(!tok) token_type = VARIABLE;
    else token_type = COMMAND; // is a command 
  }
  return token_type;
}
 
// Return a token to input stream. 
void putback() 
{
 
  char *t; 
 
  t = token; 
  for(; *t; t++) prog--; 
}
 
/* Look up a token's internal representation in the
   token table.
*/
SBtokensT look_up(char *s)
{
  register int i;
  char *p;
 
  // convert to lowercase 
  p = s;
  while(*p){ 
    *p = tolower(*p);
    p++;
  }
 
  // see if token is in table 
  for(i=0; *table[i].command; i++)
    if(!strcmp(table[i].command, s))
      return table[i].tok;
  return UNKNCOM; // unknown command
}
 
// Return true if c is a delimiter. 
bool isdelim(char c)
{
  if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c==0) 
    return true;  
  return false; 
}
 
// Return true if c is space or tab. 
bool is_sp_tab(char c)
{
  if(c==' ' || c=='\t') return true;
  else return false;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2019, 20:22
Ответы с готовыми решениями:

Парсер
Доброго времени суток форумчане! Хочу написать парсер (я великий велосипедист). Язык реализации...

Парсер
Возник вопрос как лучше написать парсер. Интересно просто услышать советы. Грамматика примерно...

Парсер
Здраствуйте! Есть видео файл. Я хочу найти в нем определенную структуру. Для этого мне нужно...

Парсер
Помогите пожалуйста сделать примитивный парсер для какого-нибудь языка. Хотя бы опишите как он...

15
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
14.01.2019, 20:29 2
код написан под c++17 стандарт. Возможно ваш компилятор не поддерживает его и ругается. Для того, чтобы всё заработало нужно установить новый компилятор, либо даже новую IDE. Для того, чтобы лучше понять что не так напишите в чем вы разрабатываете и какой у вас компилятор
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
14.01.2019, 20:39 3
Цитата Сообщение от mvngr Посмотреть сообщение
код написан под c++17 стандарт
На основании чего сделаны такие выводы?

Код не является полным: все, что объявлено со спецификатором extern должно быть описано где-то в другой части программы, функция main() отсутствует. Возможно, это один из файлов исходного кода большого проекта.
0
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
14.01.2019, 20:41 4
valen10, используется register

Upd: виноват, плохо вчитался в выхлоп Qt Creator + MinGW
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
14.01.2019, 20:45 5
Цитата Сообщение от mvngr Посмотреть сообщение
используется register
Этот спецификатор существует еще со времён языка Си. Подсказывает компилятору разместить переменную в регистре, но компилятор не обязан этому следовать. А вот начиная с C++17 этот спецификатор объявлен устаревшим.
0
223 / 188 / 97
Регистрация: 15.04.2018
Сообщений: 718
14.01.2019, 20:46 6
valen10,
Цитата Сообщение от mvngr Посмотреть сообщение
виноват, плохо вчитался в выхлоп Qt Creator + MinGW
0
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
14.01.2019, 21:25  [ТС] 7
mvngr, у меня стоит Visual Studio 2017

Добавлено через 2 минуты
valen10, там есть только еще один файл, но это уже другая часть.
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
536
537
538
539
540
541
542
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstdlib>
#include <cstring>
using namespace std;
 
const int NUM_LAB = 100;
const int LAB_LEN = 10; 
const int FOR_NEST = 25;
const int SUB_NEST = 25;
const int PROG_SIZE = 10000;
 
// The Small Basic token types.
enum typesT { UNDEFTOK, OPERATOR, NUMBER, VARIABLE, COMMAND,
              STRING, QUOTE };
 
// The Small Basic command tokens.
enum SBtokensT { UNKNCOM, PRINT, INPUT, IF, THEN, FOR, NEXT, TO,
                 GOTO, GOSUB, RETURN, EOL, FINISHED, END };
 
/* These are the constants used to call serror() when
   a syntax error occurs.  Add more if you like.
   NOTE: SERROR is a generic error message used when
   nothing else seems appropriate. */
enum errorsT
      { SERROR, PARENS, NOEXP, DIV_ZERO, EQUAL_EXP,
      NOT_VAR, LAB_TAB_FULL, DUP_LAB, UNDEF_LAB,
      THEN_EXP, TO_EXP, TOO_MNY_FOR, NEXT_WO_FOR,
      TOO_MNY_GOSUB, RET_WO_GOSUB, MISS_QUOTE };
 
char *prog; // points into the program 
char *p_buf; // points to start of program
 
int variables[26]= { // 26 user variables,  A-Z
  0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0
};
 
// keyword lookup table
struct commands { 
  char command[20]; // string form 
  SBtokensT tok; // internal representation 
} table[] = { // commands must be entered lowercase 
  "print", PRINT, // in this table. 
  "input", INPUT,
  "if", IF,
  "then", THEN,
  "goto", GOTO,
  "for", FOR,
  "next", NEXT,
  "to", TO,
  "gosub", GOSUB,
  "return", RETURN,
  "end", END,
  "", END  // mark end of table 
};
 
char token[80];
typesT token_type;
SBtokensT tok;
 
// label lookup table 
struct label {
  char name[LAB_LEN]; // label 
  char *p; // points to label's location in source file 
} label_table[NUM_LAB];
 
// support for FOR loops 
struct for_stack {
  int var; // counter variable 
  int target; // target value 
  char *loc; // place in source code to loop to 
} fstack[FOR_NEST]; // stack for FOR/NEXT loop
 
char *gstack[SUB_NEST]; // stack for gosub 
 
int ftos;  // index to top of FOR stack
int gtos;  // index to top of GOSUB stack
 
void print();
void scan_labels();
void find_eol();
void exec_goto();
void exec_if();
void exec_for();
void next();
void fpush(struct for_stack i);
void input();
void gosub();
void greturn();
void gpush(char *s);
void label_init();
void assignment();
char *find_label(char *s);
char *gpop();
struct for_stack fpop();
bool load_program(char *p, char *fname);
int get_next_label(char *s);
 
// prototypes for functions in the parser file 
void eval_exp(int &result);
typesT get_token();
void serror(errorsT error), putback();
 
int main(int argc, char *argv[])
{
  if(argc!=2) {
    cout << "Usage: sbasic <filename>\n";
    return 1;
  }
 
  // allocate memory for the program 
  try {
    prog = new char [PROG_SIZE];
  } catch(bad_alloc xa) {
    cout << "Allocation Failure\n";
    return 1;
  }
 
  p_buf = prog;
  
  // load the program to execute 
  if(!load_program(prog, argv[1])) return 1;
 
  // begin main interpreter try block
  try {
    scan_labels(); // find the labels in the program 
    ftos = 0; // initialize the FOR stack index 
    gtos = 0; // initialize the GOSUB stack index
    do {
      token_type = get_token();
      // check for assignment statement 
      if(token_type==VARIABLE) {
        putback(); // return the var to the input stream 
        assignment(); // must be assignment statement 
      }
      else // is command
        switch(tok) {
          case PRINT:
            print();
            break;
          case GOTO:
            exec_goto();
            break;
          case IF:
            exec_if();
            break;
          case FOR:
            exec_for();
            break;
          case NEXT:
            next();
            break;
          case INPUT:
            input();
            break;
          case GOSUB:
            gosub();
            break;
          case RETURN:
            greturn();
             break;
          case END:
            return 0;
        }
    } while (tok != FINISHED);
  } // end of try block
 
  /* catch throws here.  As implemented, only
     serror() throws an exception.  However, 
     when creating your own languages, you can
     throw a variety of different exceptions.
  */
  catch(int) {
    return 1; // fatal error 
  }
 
  return 0;
}
 
// Load a program.
bool load_program(char *p, char *fname)
{
  ifstream in(fname, ios::in | ios::binary);
  int i=0;
 
  if(!in) {
    cout << "File not found ";
    cout << "-- be sure to specify .BAS extension.\n";
    return false;
  }
  
  i = 0;
  do {
    *p = in.get();
    p++; i++;
  } while(!in.eof() && i<PROG_SIZE);
 
  // null terminate the program
  if(*(p-2)==0x1a) *(p-2) = '\0'; // discard eof marker
  else *(p-1) = '\0';
 
  in.close();
  return true;
}
 
// Find all labels. 
void scan_labels()
{
  int addr;
  char *temp;
 
  label_init(); // zero all labels 
  temp = prog;  // save pointer to top of program 
 
  // if the first token in the file is a label 
  get_token();
  if(token_type==NUMBER) {
    strcpy(label_table[0].name, token);
    label_table[0].p = prog;
  }
 
  find_eol();
  do {     
    get_token();
    if(token_type==NUMBER) {
      addr = get_next_label(token);
      if(addr == -1 || addr == -2) {
        (addr == -1) ? serror(LAB_TAB_FULL) : serror(DUP_LAB);
      }
      strcpy(label_table[addr].name, token);
     
      // save current location in program 
      label_table[addr].p = prog;
    }
 
    // if not on a blank line, find next line 
    if(tok!=EOL) find_eol();
  } while(tok!=FINISHED);
  prog = temp; // restore original location
}
 
// Find the start of the next line.
void find_eol()
{
  while(*prog!='\n'  && *prog!='\0') ++prog;
  if(*prog) prog++;
}
 
/* Return index of next free position in label array. 
   -1 is returned if the array is full.
   -2 is returned when duplicate label is found.
*/
int get_next_label(char *s)
{
  register int i;
 
  for(i=0; i<NUM_LAB; ++i) {
    if(label_table[i].name[0]==0) return i;
    if(!strcmp(label_table[i].name, s)) return -2;
  }
 
  return -1;
}
 
/* Find location of given label.  A null is returned
   if label is not found; otherwise a pointer to the
   position of the label is returned.
*/
char *find_label(char *s)
{
  register int i;
 
  for(i=0; i<NUM_LAB; ++i) 
    if(!strcmp(label_table[i].name, s)) 
      return label_table[i].p;
  return 0; // error condition 
}
 
/* Initialize the array that holds the labels. 
   By convention, a null label name indicates that
   the array position is unused.
*/
void label_init()
{
  register int i;
 
  for(i=0; i<NUM_LAB; ++i) 
    label_table[i].name[0] = 0;
}
 
// Assign a variable a value.
void assignment()
{
  int var, value;
 
  // get the variable name
  get_token();
  if(!isalpha(*token)) {
    serror(NOT_VAR);
    return;
  }
 
  // convert to index into variable table
  var = toupper(*token)-'A';
 
  // get the equal sign
  get_token();
  if(*token != '=') {
    serror(EQUAL_EXP);
    return;
  }
 
  // get the value to assign 
  eval_exp(value);
 
  // assign the value
  variables[var] = value;
}
 
// Execute a simple version of the BASIC PRINT statement.
void print()
{
  int result;
  int len=0, spaces;
  char last_delim, str[80];
 
  do {
    get_token(); // get next list item 
    if(tok==EOL || tok==FINISHED) break;
    if(token_type==QUOTE) { // is string
      cout << token;
      len += strlen(token);
      get_token();
    }
    else { // is expression
      putback();
      eval_exp(result);
      get_token();
      cout << result;
      itoa(result, str, 10);
      len += strlen(str); // save length
    }
    last_delim = *token; 
 
    // if comma, move to next tab stop 
    if(*token == ',') {
      // compute number of spaces to move to next tab
      spaces = 8 - (len % 8); 
      len += spaces; // add in the tabbing position
      while(spaces) { 
        cout << " ";
        spaces--;
      }
    }
    else if(*token==';') {
      cout << " ";
      len++;
    }
    else if(tok!=EOL && tok!=FINISHED) serror(SERROR); 
  } while (*token==';' || *token==',');
 
  if(tok==EOL || tok==FINISHED) {
    if(last_delim != ';' && last_delim != ',')
      cout << endl;
  }
  else serror(SERROR); 
 
}
 
// Execute a GOTO statement. 
void exec_goto()
{
  char *loc;
 
  get_token(); // get label to go to 
 
  // find the location of the label 
  loc = find_label(token);
  if(loc==NULL)
    serror(UNDEF_LAB); // label not defined 
 
  else prog = loc;  // start program running at that loc
}
 
// Execute an IF statement.
void exec_if()
{
  int result;
 
  eval_exp(result); // get value of expression
 
  if(result) { // is true so process target of IF 
    get_token();
    if(tok!=THEN) {
      serror(THEN_EXP);
      return;
    } // else, target statement will be executed 
  }
  else find_eol(); // find start of next line 
}
 
// Execute a FOR loop. 
void exec_for()
{
  struct for_stack stckvar;
  int value;
 
  get_token(); // read the control variable 
  if(!isalpha(*token)) {
    serror(NOT_VAR);
    return;
  }
  // save index of control var
  stckvar.var = toupper(*token)-'A';
 
  get_token(); // read the equal sign
  if(*token != '=') {
    serror(EQUAL_EXP);
    return;
  }
 
  eval_exp(value); // get initial value 
 
  variables[stckvar.var] = value;
 
  get_token();
  if(tok!=TO) serror(TO_EXP); // read and discard the TO
 
  eval_exp(stckvar.target); // get target value
 
  /* if loop can execute at least once,
     push info on stack */
  if(value >= variables[stckvar.var]) { 
    stckvar.loc = prog;
    fpush(stckvar);
  }
  else // otherwise, skip loop code altogether
    while(tok!=NEXT) get_token();
}
 
// Execute a NEXT statement. 
void next()
{
  struct for_stack stckvar;
 
  stckvar = fpop(); // read the loop info
 
  variables[stckvar.var]++; // increment control var
 
  // if done, return
  if(variables[stckvar.var] > stckvar.target) return; 
 
  fpush(stckvar);  // otherwise, restore the info
  prog = stckvar.loc;  // loop 
}
 
// Push the FOR stack.
void fpush(struct for_stack stckvar)
{
  if(ftos==FOR_NEST)
    serror(TOO_MNY_FOR);
 
  fstack[ftos] = stckvar;
  ftos++;
}
 
// Pop the FOR stack.
struct for_stack fpop()
{
  if(ftos==0) 
    serror(NEXT_WO_FOR);
 
  ftos--;
  return(fstack[ftos]);
}
 
// Execute a simple form of the BASIC INPUT command. 
void input()
{
  char var;
  int i;
 
  get_token(); // see if prompt string is present 
  if(token_type==QUOTE) {
    cout << token; // if so, print it and check for comma 
    get_token();
    if(*token != ',') serror(SERROR);
    get_token();
  }
  else cout << "? "; // otherwise, prompt with ?
  var = toupper(*token)-'A'; // get the input var 
 
  cin >> i; // read input 
 
  variables[var] = i; // store it 
}
 
// Execute a GOSUB command. 
void gosub()
{
  char *loc;
 
  get_token();
 
  // find the label to call
  loc = find_label(token);
  if(loc==NULL)
    serror(UNDEF_LAB); // label not defined 
  else {
    gpush(prog); // save place to return to 
    prog = loc;  // start program running at that loc
  }
}
 
// Return from GOSUB.
void greturn()
{
   prog = gpop();
}
 
// Push GOSUB stack. 
void gpush(char *s)
{
  if(gtos==SUB_NEST)
    serror(TOO_MNY_GOSUB);
 
  gstack[gtos] = s;
  gtos++;
}
 
// Pop GOSUB stack. 
char *gpop()
{
  if(gtos==0)
    serror(RET_WO_GOSUB);
 
  gtos--;
  return(gstack[gtos]);
}
0
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
14.01.2019, 21:35 8
Чистейший С++ а-ля 98. Никаких C++17 не вижу.
Компилер ругается только на небезопасные строковые и символьные функции. Заменить на безопасные версии и всё должно пройти.
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
14.01.2019, 21:42 9
Цитата Сообщение от valery7 Посмотреть сообщение
там есть только еще один файл, но это уже другая часть.
В самой книге что по этому поводу сказано? Скажите пожалуйста название книги, если это не секрет.
0
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
14.01.2019, 21:46  [ТС] 10
jugu, это то, что касается второй программы, которую я кинула. Там я все меняла.
Я про нее и не спрашивала, но первая не проходит. Я не понимаю, что там поменять надо

Добавлено через 28 секунд
valen10, Фридман и др. "Архив программ"

Добавлено через 56 секунд
valen10, если я ничего не пропустила, то ничего не сказано, поэтому и не понимаю.
0
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
14.01.2019, 21:52 11
Цитата Сообщение от valery7 Посмотреть сообщение
jugu, это то, что касается второй программы, которую я кинула. Там я все меняла.
Я про нее и не спрашивала, но первая не проходит. Я не понимаю, что там поменять надо
А где в первой программе точка входа, то бишь main? Я ее не вижу вообще...
0
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
14.01.2019, 21:58  [ТС] 12
jugu, да, main не представлен, в книге его нет, но ведь помимо этого там 10 ошибок, как минимум, которые не касаются того, что нет точки входа.
0
610 / 415 / 151
Регистрация: 11.01.2019
Сообщений: 1,746
14.01.2019, 22:03 13
Цитата Сообщение от valery7 Посмотреть сообщение
jugu, да, main не представлен, в книге его нет, но ведь помимо этого там 10 ошибок, как минимум, которые не касаются того, что нет точки входа.
Вставил ваш код в пустой консольный проект. Скриншот во вложении... Всё скомпилилось нормально с парой предупреждений о register.
Миниатюры
Парсер  
0
Параллельный Кот
1905 / 827 / 350
Регистрация: 25.03.2016
Сообщений: 2,045
14.01.2019, 22:16 14
Лучший ответ Сообщение было отмечено valery7 как решение

Решение

valery7, судя по тексту в книге, оба этих файла являются частями общего проекта, и ни один из них не является самостоятельным. Оба файла необходимо добавить в проект для успешной сборки.
Парсер


В подтверждение этого сравним их содержимое. В одном из них (SBPARSER.CPP) объявлен набор функций и набор переменных со спецификатором extern, функции main() тут нет и без нее не получится собрать исполняемый модуль. Сами эти переменные описаны в другом файле (SBASIC.CPP), там же вызываются эти функции. Без первого файла с его определением функций собрать исполняемый модуль тоже не выйдет.
Парсер
1
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
14.01.2019, 22:18  [ТС] 15
Я тоже загружала в пустой проект, вот так у меня
Миниатюры
Парсер  
0
1 / 1 / 1
Регистрация: 11.04.2018
Сообщений: 45
14.01.2019, 22:22  [ТС] 16
valen10, прошу прощения. Не внимательно прочла..
Вопрос закрыт. Все успешно скомпилировалось.
0
14.01.2019, 22:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.01.2019, 22:22
Помогаю со студенческими работами здесь

парсер
Добрый день, у меня возникла вот такая вот проблема... При работе парсера, он разделяет строки...

Парсер с нуля
Здравствуйте. Понимаю что тема наверняка не новая, хочу написать парсер (сайта) с нуля c++ это...

Наипростейший парсер
Никак не могу вникнуть в простейшй парсер математического выражения. Мне нужно просто просчитать...

Парсер паскаля
Добрый день. Задача такая: нужно на С++ написать парсер паскаля, так чтоб тот по коду мог вызывать...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru