-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
lexical.l
457 lines (402 loc) · 18.7 KB
/
lexical.l
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
/*
* Copyright (C) 2022 Clownacy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
%option never-interactive
%option nounistd
%option nounput noinput noyywrap
%option reentrant bison-bridge
%option prefix="m68kasm_"
%option caseless
%{
#include <stdlib.h>
#include <string.h>
#include "syntactic.h"
void m68kasm_warning(void *scanner, Statement *statement, const char *message);
void m68kasm_error(void *scanner, Statement *statement, const char *message);
static cc_bool CharacterToInteger(unsigned int* const value, const unsigned int character)
{
if (character >= '0' && character <= '9')
*value = 0x0 + (character - '0');
else if (character >= 'A' && character <= 'Z')
*value = 0xA + (character - 'A');
else if (character >= 'a' && character <= 'z')
*value = 0xA + (character - 'a');
else
return cc_false;
return cc_true;
}
/* Like `strtoul`, except this one returns a truncated value when parsing a number that is too large. */
static cc_bool StringTo32BitInteger(unsigned long* const value, const char* const string_start, const char** const string_end, const unsigned long base)
{
cc_bool success = cc_true;
const unsigned long limit = 0xFFFFFFFF / base;
const char* string_pointer;
*value = 0;
for (string_pointer = string_start; ; ++string_pointer)
{
unsigned int digit;
if (!CharacterToInteger(&digit, *string_pointer) || digit >= base)
break;
if (*value > limit)
success = cc_false;
*value *= base;
*value += digit;
}
*string_end = string_pointer;
return success;
}
static cc_bool ParseNumber(unsigned long* const value, void* const scanner, const char* const string_start, const size_t string_length, const unsigned long base)
{
const char *string_end;
if (!StringTo32BitInteger(value, string_start, &string_end, base))
{
/* S.N. 68k silently truncates values that are too large. This is relied upon by old versions of the Sonic 2 August 21st prototype disassembly. */
m68kasm_warning(scanner, NULL, "Number is too large and will be truncated.");
}
if (string_end != string_start + string_length)
{
m68kasm_error(scanner, NULL, "Number is invalid and cannot be parsed.");
return cc_false;
}
return cc_true;
}
%}
/* Regular expression. */
binary_digit [0-1]
decimal_digit [0-9]
hexadecimal_digit [0-9a-fA-F]
binary {binary_digit}+
decimal {decimal_digit}+
hexadecimal {hexadecimal_digit}+
%s OPERANDS PATH
%%
/* Ignore whitespace */
[ \t]+ ;
/* Terminate at comment or newline. When terminating, revert to initial state. */
<<EOF>> |
[;\r\n] BEGIN(INITIAL); yyterminate();
/* Directives. */
<INITIAL>ori BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ORI;
<INITIAL>andi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ANDI;
<INITIAL>subi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SUBI;
<INITIAL>addi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ADDI;
<INITIAL>eori BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EORI;
<INITIAL>cmpi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CMPI;
<INITIAL>btst BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BTST;
<INITIAL>bchg BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCHG;
<INITIAL>bclr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCLR;
<INITIAL>bset BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BSET;
<INITIAL>movep BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MOVEP;
<INITIAL>movea BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MOVEA;
<INITIAL>move BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MOVE;
<INITIAL>negx BEGIN(OPERANDS); return TOKEN_DIRECTIVE_NEGX;
<INITIAL>clr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CLR;
<INITIAL>neg BEGIN(OPERANDS); return TOKEN_DIRECTIVE_NEG;
<INITIAL>not BEGIN(OPERANDS); return TOKEN_DIRECTIVE_NOT;
<INITIAL>ext BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EXT;
<INITIAL>nbcd BEGIN(OPERANDS); return TOKEN_DIRECTIVE_NBCD;
<INITIAL>swap BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SWAP;
<INITIAL>pea BEGIN(OPERANDS); return TOKEN_DIRECTIVE_PEA;
<INITIAL>illegal BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ILLEGAL;
<INITIAL>tas BEGIN(OPERANDS); return TOKEN_DIRECTIVE_TAS;
<INITIAL>tst BEGIN(OPERANDS); return TOKEN_DIRECTIVE_TST;
<INITIAL>trap BEGIN(OPERANDS); return TOKEN_DIRECTIVE_TRAP;
<INITIAL>link BEGIN(OPERANDS); return TOKEN_DIRECTIVE_LINK;
<INITIAL>unlk BEGIN(OPERANDS); return TOKEN_DIRECTIVE_UNLK;
<INITIAL>reset BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RESET;
<INITIAL>nop BEGIN(OPERANDS); return TOKEN_DIRECTIVE_NOP;
<INITIAL>stop BEGIN(OPERANDS); return TOKEN_DIRECTIVE_STOP;
<INITIAL>rte BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RTE;
<INITIAL>rts BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RTS;
<INITIAL>trapv BEGIN(OPERANDS); return TOKEN_DIRECTIVE_TRAPV;
<INITIAL>rtr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RTR;
<INITIAL>jsr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_JSR;
<INITIAL>jmp BEGIN(OPERANDS); return TOKEN_DIRECTIVE_JMP;
<INITIAL>movem BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MOVEM;
<INITIAL>lea BEGIN(OPERANDS); return TOKEN_DIRECTIVE_LEA;
<INITIAL>chk BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CHK;
<INITIAL>addq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ADDQ;
<INITIAL>subq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SUBQ;
<INITIAL>st BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ST;
<INITIAL>sf BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SF;
<INITIAL>shi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SHI;
<INITIAL>sls BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SLS;
<INITIAL>scc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SCC;
<INITIAL>scs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SCS;
<INITIAL>sne BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SNE;
<INITIAL>seq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SEQ;
<INITIAL>svc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SVC;
<INITIAL>svs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SVS;
<INITIAL>spl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SPL;
<INITIAL>smi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SMI;
<INITIAL>sge BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SGE;
<INITIAL>slt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SLT;
<INITIAL>sgt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SGT;
<INITIAL>sle BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SLE;
<INITIAL>shs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SCC;
<INITIAL>slo BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SCS;
<INITIAL>dbt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBT;
<INITIAL>dbf BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBF;
<INITIAL>dbhi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBHI;
<INITIAL>dbls BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBLS;
<INITIAL>dbcc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBCC;
<INITIAL>dbcs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBCS;
<INITIAL>dbne BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBNE;
<INITIAL>dbeq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBEQ;
<INITIAL>dbvc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBVC;
<INITIAL>dbvs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBVS;
<INITIAL>dbpl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBPL;
<INITIAL>dbmi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBMI;
<INITIAL>dbge BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBGE;
<INITIAL>dblt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBLT;
<INITIAL>dbgt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBGT;
<INITIAL>dble BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBLE;
<INITIAL>dbhs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBCC;
<INITIAL>dblo BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBCS;
<INITIAL>dbra BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DBF;
<INITIAL>bra BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BRA;
<INITIAL>bsr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BSR;
<INITIAL>bhi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BHI;
<INITIAL>bls BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BLS;
<INITIAL>bcc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCC;
<INITIAL>bcs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCS;
<INITIAL>bne BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BNE;
<INITIAL>beq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BEQ;
<INITIAL>bvc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BVC;
<INITIAL>bvs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BVS;
<INITIAL>bpl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BPL;
<INITIAL>bmi BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BMI;
<INITIAL>bge BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BGE;
<INITIAL>blt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BLT;
<INITIAL>bgt BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BGT;
<INITIAL>ble BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BLE;
<INITIAL>bhs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCC;
<INITIAL>blo BEGIN(OPERANDS); return TOKEN_DIRECTIVE_BCS;
<INITIAL>moveq BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MOVEQ;
<INITIAL>divu BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DIVU;
<INITIAL>divs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DIVS;
<INITIAL>sbcd BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SBCD;
<INITIAL>or BEGIN(OPERANDS); return TOKEN_DIRECTIVE_OR;
<INITIAL>sub BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SUB;
<INITIAL>subx BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SUBX;
<INITIAL>suba BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SUBA;
<INITIAL>eor BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EOR;
<INITIAL>cmpm BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CMPM;
<INITIAL>cmp BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CMP;
<INITIAL>cmpa BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CMPA;
<INITIAL>mulu BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MULU;
<INITIAL>muls BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MULS;
<INITIAL>abcd BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ABCD;
<INITIAL>exg BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EXG;
<INITIAL>and BEGIN(OPERANDS); return TOKEN_DIRECTIVE_AND;
<INITIAL>add BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ADD;
<INITIAL>addx BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ADDX;
<INITIAL>adda BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ADDA;
<INITIAL>asl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ASL;
<INITIAL>asr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ASR;
<INITIAL>lsl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_LSL;
<INITIAL>lsr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_LSR;
<INITIAL>roxl BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ROXL;
<INITIAL>roxr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ROXR;
<INITIAL>rol BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ROL;
<INITIAL>ror BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ROR;
<INITIAL>dc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DC;
<INITIAL>dcb BEGIN(OPERANDS); return TOKEN_DIRECTIVE_DCB;
<INITIAL>rept BEGIN(OPERANDS); return TOKEN_DIRECTIVE_REPT;
<INITIAL>endr BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ENDR;
<INITIAL>macro BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MACRO;
<INITIAL>macros BEGIN(OPERANDS); return TOKEN_DIRECTIVE_MACROS;
<INITIAL>endm BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ENDM;
<INITIAL>include BEGIN(PATH); return TOKEN_DIRECTIVE_INCLUDE;
<INITIAL>incbin BEGIN(PATH); return TOKEN_DIRECTIVE_INCBIN;
<INITIAL>binclude BEGIN(PATH); return TOKEN_DIRECTIVE_INCBIN;
<INITIAL>equ BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EQU;
<INITIAL>set BEGIN(OPERANDS); return TOKEN_DIRECTIVE_SET;
<INITIAL>if BEGIN(OPERANDS); return TOKEN_DIRECTIVE_IF;
<INITIAL>elseif BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ELSEIF;
<INITIAL>else BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ELSE;
<INITIAL>endc BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ENDC;
<INITIAL>endif BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ENDC;
<INITIAL>while BEGIN(OPERANDS); return TOKEN_DIRECTIVE_WHILE;
<INITIAL>endw BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ENDW;
<INITIAL>even BEGIN(OPERANDS); return TOKEN_DIRECTIVE_EVEN;
<INITIAL>cnop BEGIN(OPERANDS); return TOKEN_DIRECTIVE_CNOP;
<INITIAL>inform BEGIN(OPERANDS); return TOKEN_DIRECTIVE_INFORM;
<INITIAL>end BEGIN(OPERANDS); return TOKEN_DIRECTIVE_END;
<INITIAL>rs BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RS;
<INITIAL>rsset BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RSSET;
<INITIAL>rsreset BEGIN(OPERANDS); return TOKEN_DIRECTIVE_RSRESET;
<INITIAL>obj BEGIN(OPERANDS); return TOKEN_DIRECTIVE_OBJ;
<INITIAL>objend BEGIN(OPERANDS); return TOKEN_DIRECTIVE_OBJEND;
<INITIAL>org BEGIN(OPERANDS); return TOKEN_DIRECTIVE_ORG;
/* Sizes. */
".b" return TOKEN_SIZE_BYTE;
".s" return TOKEN_SIZE_SHORT;
".w" return TOKEN_SIZE_WORD;
".l" return TOKEN_SIZE_LONGWORD;
/* Misc. symbols. */
"." return yytext[0];
"," return yytext[0];
"(" return yytext[0];
")" return yytext[0];
"$" return yytext[0];
"+" return yytext[0];
"-" return yytext[0];
"*" return yytext[0];
"/" return yytext[0];
"=" return yytext[0];
"@" return yytext[0];
/* Operators. */
"&&" return TOKEN_LOGICAL_AND;
"||" return TOKEN_LOGICAL_OR;
"==" return TOKEN_EQUALITY; /* An assembler extension, for programmers that are familiar with C. */
"!=" return TOKEN_INEQUALITY; /* An assembler extension, for programmers that are familiar with C. */
"<>" return TOKEN_INEQUALITY;
"><" return TOKEN_INEQUALITY;
"<=" return TOKEN_LESS_OR_EQUAL;
">=" return TOKEN_MORE_OR_EQUAL;
"<<" return TOKEN_LEFT_SHIFT;
">>" return TOKEN_RIGHT_SHIFT;
/* Operands. */
sr return TOKEN_STATUS_REGISTER;
ccr return TOKEN_CONDITION_CODE_REGISTER;
sp yylval->unsigned_long = 7; return TOKEN_ADDRESS_REGISTER;
usp return TOKEN_USER_STACK_POINTER_REGISTER;
pc return TOKEN_PROGRAM_COUNTER;
/* Functions. */
strlen return TOKEN_STRLEN;
def return TOKEN_DEF;
/* Decimal number. */
{decimal} {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext, strlen(yytext), 10))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Hexadecimal number (68k). */
\${hexadecimal} {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext + 1, strlen(yytext + 1), 16))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Binary number (68k). */
\%{binary} {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext + 1, strlen(yytext + 1), 2))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Hexadecimal number (Z80). */
[0-9]{hexadecimal}?h {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext, strlen(yytext) - 1, 16))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Binary number (Z80). */
{binary}b {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext, strlen(yytext) - 1, 2))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Hexadecimal number (C). */
0x{hexadecimal} {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext + 2, strlen(yytext + 2), 16))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* Binary number (GNU C). */
0b{binary} {
if (!ParseNumber(&yylval->unsigned_long, yyscanner, yytext + 2, strlen(yytext + 2), 2))
return M68KASM_error;
return TOKEN_NUMBER;
}
/* String. */
\"[^\"]+\" |
\'[^\']+\' {
const size_t length = strlen(yytext) - 2;
/* Escape PATH mode so that the following arguments use the correct rules. */
BEGIN(OPERANDS);
yylval->string = (char*)malloc(length + 1);
if (yylval->string == NULL)
{
m68kasm_error(yyscanner, NULL, "Could not allocate memory for generic string.");
return M68KASM_error;
}
else
{
memcpy(yylval->string, yytext + 1, length);
yylval->string[length] = '\0';
return TOKEN_STRING;
}
}
/* File path (like a string, but it doesn't need to be wrapped in quotation marks). */
<PATH>[^, \t;]([^,;]*[^, \t;])? {
const size_t length = strlen(yytext);
/* Escape PATH mode so that the following arguments use the correct rules. */
BEGIN(OPERANDS);
yylval->string = (char*)malloc(length + 1);
if (yylval->string == NULL)
{
m68kasm_error(yyscanner, NULL, "Could not allocate memory for generic string.");
return M68KASM_error;
}
else
{
memcpy(yylval->string, yytext, length + 1);
return TOKEN_STRING;
}
}
/* Identifier, data register, or address register. */
[A-Za-z_][A-Za-z_0-9\?]* {
if (yytext[2] == '\0' && (yytext[0] == 'd' || yytext[0] == 'D' || yytext[0] == 'a' || yytext[0] == 'A') && yytext[1] >= '0' && yytext[1] <= '7')
{
/* Data register or address register. */
yylval->unsigned_long = yytext[1] - '0';
return yytext[0] == 'd' || yytext[0] == 'D' ? TOKEN_DATA_REGISTER : TOKEN_ADDRESS_REGISTER;
}
else
{
/* Identifier. */
const size_t length = strlen(yytext);
yylval->string = (char*)malloc(length + 1);
if (yylval->string == NULL)
{
m68kasm_error(yyscanner, NULL, "Could not allocate memory for generic string.");
return M68KASM_error;
}
else
{
memcpy(yylval->string, yytext, length + 1);
return TOKEN_IDENTIFIER;
}
}
}
/* Local label. */
[@\.][A-Za-z_0-9\?]+ {
const size_t length = strlen(yytext);
yylval->string = (char*)malloc(length + 1);
if (yylval->string == NULL)
{
m68kasm_error(yyscanner, NULL, "Could not allocate memory for generic string.");
return M68KASM_error;
}
else
{
memcpy(yylval->string, yytext, length + 1);
return TOKEN_LOCAL_IDENTIFIER;
}
}
/* Make Bison signal a syntax error for unrecognised symbols */
. return yytext[0];
%%