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
|
%{
#include <stdio.h>
#include "lexer.h"
#include "mnemonics.h"
void yyerror(const char *msg)
{
fprintf(stderr, "%s\n", msg);
}
#define INSTRUCTION_ARGS(m,a) (struct instruction) { MNEM_ ## m, a }
#define INSTRUCTION(m) (struct instruction) { MNEM_ ## m }
#define MKARGS(...) (struct arguments) { __VA_ARGS__ }
#define MKARGVALUE(v) (struct argument) { (v) }
%}
%output "parser.c"
%defines "parser.h"
%code requires {
#include "nqasm.h"
}
%union {
struct instruction inst;
struct arguments args;
struct argument arg;
long lval;
}
%token END 0 "end of file"
%token T_SPACE
%token T_EOL
%token T_ADD
%token T_SUB
%token T_MUL
%token T_DIV
%token T_AND
%token T_OR
%token T_XOR
%token T_LSL
%token T_LSR
%token T_ASL
%token T_ASR
%token T_ROL
%token T_ROR
%token T_NOT
%token T_NEG
%token T_BTC
%token T_BTS
%token T_MOV
%token T_ST_B
%token T_ST_W
%token T_LD_BL
%token T_LD_BH
%token T_LD_W
%token T_LDI_BL
%token T_LDI_BH
%token T_BEQ
%token T_BNE
%token T_BGT
%token T_BGE
%token T_BLT
%token T_BLE
%token T_BRA
%token T_JMP
%token T_ADDPC
%token T_NOP
%token <lval> T_INT
%token T_BADINT
%token <arg> T_REG
%token <arg> T_REGPTR
%token T_COMMA ","
%type <inst> inst
%type <arg> imm
%type <args> reg2
%type <args> reg3
%type <args> regp
%type <args> regp_reg
%type <args> reg_regp
%type <args> reg_imm
%type <lval> intlit
%%
input: line
| input line
;
line: T_SPACE inst eol
{ add_instruction(&$2); }
| eol
;
inst: T_ADD reg3 { $$ = INSTRUCTION_ARGS(ADD, $2); }
| T_SUB reg3 { $$ = INSTRUCTION_ARGS(SUB, $2); }
| T_MUL reg3 { $$ = INSTRUCTION_ARGS(MUL, $2); }
| T_DIV reg3 { $$ = INSTRUCTION_ARGS(DIV, $2); }
| T_AND reg3 { $$ = INSTRUCTION_ARGS(AND, $2); }
| T_OR reg3 { $$ = INSTRUCTION_ARGS(OR, $2); }
| T_XOR reg3 { $$ = INSTRUCTION_ARGS(XOR, $2); }
| T_LSL reg3 { $$ = INSTRUCTION_ARGS(LSL, $2); }
| T_LSR reg3 { $$ = INSTRUCTION_ARGS(LSR, $2); }
| T_ASL reg3 { $$ = INSTRUCTION_ARGS(ASL, $2); }
| T_ASR reg3 { $$ = INSTRUCTION_ARGS(ASR, $2); }
| T_ROL reg3 { $$ = INSTRUCTION_ARGS(ROL, $2); }
| T_ROR reg3 { $$ = INSTRUCTION_ARGS(ROR, $2); }
| T_NOT reg2 { $$ = INSTRUCTION_ARGS(NOT, $2); }
| T_NEG reg2 { $$ = INSTRUCTION_ARGS(NEG, $2); }
| T_BTC reg2 { $$ = INSTRUCTION_ARGS(BTC, $2); }
| T_BTS reg2 { $$ = INSTRUCTION_ARGS(BTS, $2); }
| T_MOV reg2 { $$ = INSTRUCTION_ARGS(MOV, $2); }
| T_ST_B regp_reg { $$ = INSTRUCTION_ARGS(ST_B, $2); }
| T_ST_W regp_reg { $$ = INSTRUCTION_ARGS(ST_W, $2); }
| T_LD_BL reg_regp { $$ = INSTRUCTION_ARGS(LD_BL, $2); }
| T_LD_BH reg_regp { $$ = INSTRUCTION_ARGS(LD_BH, $2); }
| T_LD_W reg_regp { $$ = INSTRUCTION_ARGS(LD_W, $2); }
| T_LDI_BL reg_imm { $$ = INSTRUCTION_ARGS(LDI_BL, $2); }
| T_LDI_BH reg_imm { $$ = INSTRUCTION_ARGS(LDI_BH, $2); }
| T_BEQ
{ $$ = INSTRUCTION(BEQ); }
| T_BNE
{ $$ = INSTRUCTION(BNE); }
| T_BGT
{ $$ = INSTRUCTION(BGT); }
| T_BGE
{ $$ = INSTRUCTION(BGE); }
| T_BLT
{ $$ = INSTRUCTION(BLT); }
| T_BLE
{ $$ = INSTRUCTION(BLE); }
| T_BRA
{ $$ = INSTRUCTION(BRA); }
| T_JMP regp { $$ = INSTRUCTION_ARGS(JMP, $2); }
| T_ADDPC reg_imm { $$ = INSTRUCTION_ARGS(ADDPC, $2); }
| T_NOP
{ $$ = INSTRUCTION(NOP); }
;
reg2: T_SPACE T_REG "," T_REG { $$ = MKARGS($2, $4); }
reg3: T_SPACE T_REG "," T_REG "," T_REG { $$ = MKARGS($2, $4, $6); }
regp: T_SPACE T_REGPTR { $$ = MKARGS($2); }
regp_reg: T_SPACE T_REGPTR "," T_REG { $$ = MKARGS($2, $4); }
reg_regp: T_SPACE T_REG "," T_REGPTR { $$ = MKARGS($2, $4); }
reg_imm: T_SPACE T_REG "," imm { $$ = MKARGS($2, $4); }
imm: intlit {
if (-0x80 > $1 || $1 > 0xff) {
yyerror("immediate operand out of range");
YYERROR;
} else {
$$ = MKARGVALUE((uint8_t) $1);
}
}
intlit: T_INT
| T_BADINT {
yyerror("integer literal out of range");
YYERROR;
}
eol: T_EOL
| T_SPACE T_EOL
;
|