File: cmdpars.y

package info (click to toggle)
sdcc 3.8.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 99,212 kB
  • sloc: ansic: 918,594; cpp: 69,526; makefile: 56,790; sh: 29,616; asm: 12,364; perl: 12,136; yacc: 7,179; lisp: 1,672; python: 812; lex: 773; awk: 495; sed: 89
file content (421 lines) | stat: -rw-r--r-- 10,036 bytes parent folder | download
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
%{

#include "cmdlexcl.h"
#include "memcl.h"
#include "globals.h"
#include "stypes.h"

static void yyerror (const char *msg);
%}
/*%expect 6*/

%token PTOK_PLUS PTOK_MINUS PTOK_ASTERIX PTOK_SLASH PTOK_EQUAL
%token PTOK_LEFT_PAREN PTOK_RIGHT_PAREN
%token PTOK_LEFT_BRACKET PTOK_RIGHT_BRACKET
%token PTOK_DOT PTOK_AMPERSAND PTOK_PIPE PTOK_CIRCUM
%token PTOK_PERCENT PTOK_TILDE PTOK_QUESTION PTOK_COLON PTOK_EXCLAMATION
%token PTOK_LESS PTOK_GREATHER PTOK_COMMA

%token PTOK_AND_OP PTOK_OR_OP
%token PTOK_INC_OP PTOK_DEC_OP
%token PTOK_EQ_OP PTOK_NE_OP
%token PTOK_GE_OP PTOK_LE_OP
%token PTOK_LEFT_OP PTOK_RIGHT_OP

%token PTOK_MUL_ASSIGN
%token PTOK_DIV_ASSIGN
%token PTOK_MOD_ASSIGN
%token PTOK_ADD_ASSIGN
%token PTOK_SUB_ASSIGN
%token PTOK_LEFT_ASSIGN
%token PTOK_RIGHT_ASSIGN
%token PTOK_AND_ASSIGN
%token PTOK_XOR_ASSIGN
%token PTOK_OR_ASSIGN

%token PTOK_INT

%token <memory_object> PTOK_MEMORY_OBJECT
%token <memory> PTOK_MEMORY
%token <number> PTOK_NUMBER
%token <bit> PTOK_BIT

%type <number> ucsim_grammar expr
%type <number> primary_expr postfix_expr
%type <number> unary_expr cast_expr
%type <number> multiplicative_expr additive_expr shift_expr
%type <number> relational_expr equality_expr
%type <number> and_expr exclusive_or_expr inclusive_or_expr
%type <number> logical_and_expr logical_or_expr
%type <number> conditional_expr assignment_expr

%type <number> type_name assignment_operator

%type <memory> memory
%type <bit> bit

%union {
  long number;
  class cl_memory *memory_object;
  struct {
    class cl_memory *memory;
    long address;
  } memory;
  struct {
    class cl_memory *memory;
    long mem_address, bit_address;
    long mask;
  } bit;
}

%%

ucsim_grammar:
expr { application->/*dd_printf("%d\n", $1)*/expr_result=$1; }
	;
/*
assignment:
	  memory PTOK_EQUAL expression
	  {
	    $1.memory->write($1.address, $3);
	    $$= $3;
	  }
	| bit PTOK_EQUAL expression
	  {
	    if ($3)
	      {
		$1.memory->write($1.mem_address,
				 $1.memory->read($1.mem_address) | $1.mask);
		$$= 1;
	      }
	    else
	      {
		$1.memory->write($1.mem_address,
				 $1.memory->read($1.mem_address) & ~($1.mask));
		$$= 0;
	      }
	  }
	;
*/
/*
expression:
	  assignment { $$= $1; }
	| expression PTOK_PLUS expression { $$= $1 + $3; }
	| expression PTOK_MINUS expression { $$= $1 - $3; }
	| expression PTOK_ASTERIX expression { $$= $1 * $3; }
	| expression PTOK_SLASH expression
	  {
	    if ($3 == 0)
	      yyerror("Divide by zero");
	    else
	      $$= $1 / $3;
	  }
	| PTOK_MINUS expression %prec UNARYMINUS { $$= -$2; }
	| address_of_expression { $$= $1; }
	| PTOK_LEFT_PAREN expression PTOK_RIGHT_PAREN { $$= $2; }
	| PTOK_NUMBER { $$= $1; }
	| memory { $$= $1.memory->read($1.address); }
	| bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; }
	;
*/

/*
address_of_expression:
	  PTOK_AMPERSAND memory { $$= $2.address; }
	| PTOK_AMPERSAND bit
	{
	  $$= $2.bit_address;
	  if ($$ < 0)
	    {
	      yyerror("Bit has no address.");
	      $$= 0;
	    }
	}
	;
*/


primary_expr
/*   : identifier      */
: memory { $$= $1.memory->read($1.address); }
| bit { $$= ($1.memory->read($1.mem_address) & $1.mask)?1:0; }
| PTOK_NUMBER { $$= $1; }
     /*   | string_literal_val*/
| PTOK_LEFT_PAREN expr PTOK_RIGHT_PAREN { $$= $2; }
     /*   | generic_selection*/
   ;

postfix_expr
: primary_expr { $$= $1; }
/*   | postfix_expr PTOK_LEFT_BRACKET expr PTOK_RIGHT_BRACKET          */
/*   | postfix_expr PTOK_LEFT_PAREN PTOK_RIGHT_PAREN               */
/*   | postfix_expr PTOK_LEFT_PAREN argument_expr_list PTOK_RIGHT_PAREN*/
/*   | postfix_expr PTOK_DOT  identifier*/
/*   | postfix_expr PTOK_AMPERSAND  identifier*/
/*| postfix_expr PTOK_INC_OP*/
| memory PTOK_INC_OP
	{
	  $$= $1.memory->read($1.address);
	  $1.memory->write($1.address, $$+1);
	}
/*| postfix_expr PTOK_DEC_OP*/
| memory PTOK_DEC_OP
	{
	  $$= $1.memory->read($1.address);
	  $1.memory->write($1.address, $$-1);
	}
;
/*
argument_expr_list
   : assignment_expr
   | assignment_expr PTOK_COLON argument_expr_list 
   ;
*/

unary_expr
: postfix_expr { $$= $1; }
/*| PTOK_INC_OP unary_expr      */
| PTOK_INC_OP memory
	{
	  $$= $2.memory->read($2.address);
	  $2.memory->write($2.address, $$+1);
	  $$= $2.memory->read($2.address);
	}
/*| PTOK_DEC_OP unary_expr      */
| PTOK_DEC_OP memory
	{
	  $$= $2.memory->read($2.address);
	  $2.memory->write($2.address, $$-1);
	  $$= $2.memory->read($2.address);
	}
/*| unary_operator cast_expr	*/
/*| PTOK_AMPERSAND unary_expr*/
|PTOK_AMPERSAND memory { $$= $2.address; }
|PTOK_AMPERSAND bit
	{
	  $$= $2.bit_address;
	  if ($$ < 0)
	    {
	      yyerror("Bit has no address.");
	      $$= 0;
	    }
	}
| PTOK_MINUS unary_expr { $$= -$2; }
| PTOK_PLUS unary_expr { $$= +$2; }
| PTOK_TILDE unary_expr { $$= ~$2; }
| PTOK_EXCLAMATION unary_expr { $$= ($2)?0:1; }
  /*   | SIZEOF unary_expr        */
  /*   | SIZEOF PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN */
  /*   | ALIGNOF PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN*/
  /*   | TYPEOF unary_expr        */
  /*   | OFFSETOF PTOK_LEFT_PAREN type_name PTOK_COMMA offsetof_member_designator PTOK_RIGHT_PAREN */
;

/*
unary_operator
   : '&'    
   | '*'    
   | '+'    
   | '-'    
   | '~'    
   | '!'    
   ;
*/

cast_expr
: unary_expr { $$= $1; }
| PTOK_LEFT_PAREN type_name PTOK_RIGHT_PAREN /*cast_expr*/ memory
	{
	  $$= $4.memory->read($4.address);
	  if ($2 == PTOK_INT)
	    {
	      u32_t smask;
	      smask= 1 << ($4.memory->width - 1);
	      if ($$ & smask)
		{
		  u32_t mask;
		  mask= -1 & ~($4.memory->data_mask);
		  $$= $$ | mask;
		}
	    }
	}
;

type_name
: PTOK_INT { $$= PTOK_INT; }
;

multiplicative_expr
: cast_expr { $$= $1; }
| multiplicative_expr PTOK_ASTERIX cast_expr { $$= $1 * $3; }
| multiplicative_expr PTOK_SLASH cast_expr { $$= $1 / $3; }
| multiplicative_expr PTOK_PERCENT cast_expr { $$= $1 % $3; }
;

additive_expr
: multiplicative_expr { $$= $1; }
| additive_expr PTOK_PLUS multiplicative_expr { $$= $1 + $3; }
| additive_expr PTOK_MINUS multiplicative_expr { $$= $1 - $3; }
;

shift_expr
: additive_expr { $$= $1; }
| shift_expr PTOK_LEFT_OP additive_expr { $$= $1 << $3; }
| shift_expr PTOK_RIGHT_OP additive_expr { $$= $1 >> $3; }
;

relational_expr
: shift_expr { $$= $1; }
| relational_expr PTOK_LESS shift_expr { $$= ($1 < $3)?1:0; }
| relational_expr PTOK_GREATHER shift_expr { $$= ($1 > $3)?1:0; }
| relational_expr PTOK_LE_OP shift_expr { $$= ($1 <= $3)?1:0; }
| relational_expr PTOK_GE_OP shift_expr { $$= ($1 >= $3)?1:0; }
;

equality_expr
: relational_expr { $$= $1; }
| equality_expr PTOK_EQ_OP relational_expr { $$= ($1==$3)?1:0; }
| equality_expr PTOK_NE_OP relational_expr { $$= ($1!=$3)?1:0; }
;

and_expr
: equality_expr { $$= $1; }
| and_expr PTOK_AMPERSAND equality_expr { $$= $1 & $3; }
;

exclusive_or_expr
: and_expr { $$= $1; }
| exclusive_or_expr PTOK_CIRCUM and_expr { $$= $1 ^ $3; }
;

inclusive_or_expr
: exclusive_or_expr { $$= $1; }
| inclusive_or_expr PTOK_PIPE exclusive_or_expr { $$= $1 | $3; }
;

logical_and_expr
: inclusive_or_expr { $$= $1; }
| logical_and_expr PTOK_AND_OP inclusive_or_expr { $$= ($1 && $3)?1:0; }
;

logical_or_expr
: logical_and_expr { $$= $1; }
| logical_or_expr PTOK_OR_OP logical_and_expr { $$= ($1 || $3)?1:0; }
;

conditional_expr
: logical_or_expr { $$= $1; }
| logical_or_expr PTOK_QUESTION expr PTOK_COLON conditional_expr { $$= ($1)?($3):($5); }
;

assignment_expr
: conditional_expr { $$= $1; }
/*| cast_expr assignment_operator assignment_expr*/
/*| cast_expr PTOK_EQUAL assignment_expr*/
| memory assignment_operator assignment_expr
	{
	  t_mem org= $1.memory->read($1.address);
	  $$= $3;
	  switch ($2)
	    {
	    case PTOK_EQUAL:
	      $1.memory->write($1.address, $3);
	      break;
	    case PTOK_MUL_ASSIGN:
	      $1.memory->write($1.address, org *= $3);
	      break;
	    case PTOK_DIV_ASSIGN:
	      $1.memory->write($1.address, org /= $3);
	      break;
	    case PTOK_MOD_ASSIGN:
	      $1.memory->write($1.address, org %= $3);
	      break;
	    case PTOK_ADD_ASSIGN:
	      $1.memory->write($1.address, org += $3);
	      break;
	    case PTOK_SUB_ASSIGN:
	      $1.memory->write($1.address, org -= $3);
	      break;
	    case PTOK_LEFT_ASSIGN:
	      $1.memory->write($1.address, org <<= $3);
	      break;
	    case PTOK_RIGHT_ASSIGN:
	      $1.memory->write($1.address, org >>= $3);
	      break;
	    case PTOK_AND_ASSIGN:
	      $1.memory->write($1.address, org &= $3);
	      break;
	    case PTOK_XOR_ASSIGN:
	      $1.memory->write($1.address, org ^= $3);
	      break;
	    case PTOK_OR_ASSIGN:
	      $1.memory->write($1.address, org |= $3);
	      break;
	    }
	  $$= $1.memory->read($1.address);
	}
| bit PTOK_EQUAL assignment_expr
	{
	  if ($3)
	    {
	      $1.memory->write($1.mem_address,
			       $1.memory->read($1.mem_address) | $1.mask);
	      $$= 1;
	    }
	  else
	    {
	      $1.memory->write($1.mem_address,
			       $1.memory->read($1.mem_address) & ~($1.mask));
	      $$= 0;
	    }
	}
;

assignment_operator
: PTOK_EQUAL { $$= PTOK_EQUAL; }
| PTOK_MUL_ASSIGN { $$= PTOK_MUL_ASSIGN; }
| PTOK_DIV_ASSIGN { $$= PTOK_DIV_ASSIGN; }
| PTOK_MOD_ASSIGN { $$= PTOK_MOD_ASSIGN; }
| PTOK_ADD_ASSIGN { $$= PTOK_ADD_ASSIGN; }
| PTOK_SUB_ASSIGN { $$= PTOK_SUB_ASSIGN; }
| PTOK_LEFT_ASSIGN { $$= PTOK_LEFT_ASSIGN; }
| PTOK_RIGHT_ASSIGN { $$= PTOK_RIGHT_ASSIGN; }
| PTOK_AND_ASSIGN { $$= PTOK_AND_ASSIGN; }
| PTOK_XOR_ASSIGN { $$= PTOK_XOR_ASSIGN; }
| PTOK_OR_ASSIGN { $$= PTOK_OR_ASSIGN; }
;

expr
: assignment_expr { $$= $1; }
| expr PTOK_COMMA assignment_expr { $$= $3; }
;

memory:
	  PTOK_MEMORY
	| PTOK_MEMORY_OBJECT PTOK_LEFT_BRACKET expr PTOK_RIGHT_BRACKET
	  {
	    $$.memory= $1;
	    $$.address= $3;
	  }

bit:
	  PTOK_BIT
	| memory PTOK_DOT expr
	  {
	    $$.memory= $1.memory;
	    $$.mem_address= $1.address;
	    $$.mask= 1 << $3;
	    $$.bit_address= -1;
	    class cl_uc *uc= application->get_uc();
	    if (uc)
	      $$.bit_address= uc->bit_address($1.memory, $1.address, $3);
	  }
	;

%%

static void
yyerror (const char *msg)
{
  application->dd_printf ("Parser error: %s\n", msg);
}