-
Notifications
You must be signed in to change notification settings - Fork 1
/
ijvm-parse.y
120 lines (97 loc) · 2.78 KB
/
ijvm-parse.y
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
%{
#include <stdlib.h>
#include <stdio.h>
#include "ijvm-asm.h"
#define YYDEBUG 1
int yylex(void);
void yyerror(char *msg);
static JasmMethod *program;
%}
%union {
struct { char *value; int line_num; } symbol;
struct { unsigned int value; int line_num; } integer;
JasmMethod *method;
JasmOperand *operand;
JasmDir *dir;
JasmInsn *insn;
struct { IJVMInsnTemplate *tmpl; int line_num; } mnemonic;
JasmExpr *expr;
int line_num;
};
%token T_BIPUSH T_DUP T_GOTO T_IADD T_IAND T_IFEQ
%token T_IFLT T_IF_ICMPEQ T_IINC T_ILOAD T_INVOKEVIRTUAL
%token T_IOR T_IRETURN T_ISTORE T_ISUB T_LDC_W T_NOP
%token T_POP T_SWAP T_NEWLINE T_METHOD
%token <line_num> T_LOCALS T_ARGS T_DEFINE
%token <symbol> T_SYMBOL T_LABEL
%token <integer> T_INTEGER
%token <mnemonic> T_MNEMONIC
%type <method> program methods method
%type <dir> directives directive
%type <insn> insns insn
%type <expr> expr
%type <operand> operands
%left '+' '-'
%left UNARY
%%
program : methods { program = $1; }
methods:
method methods { $1->next = $2; $$ = $1; }
| method { $$ = $1; }
;
method:
T_METHOD T_SYMBOL directives insns
{ $$ = jasm_method_make ($2.value, $3, $4); }
| T_METHOD T_SYMBOL insns
{ $$ = jasm_method_make ($2.value, NULL, $3); }
;
directives:
directive directives { $1->next = $2; $$ = $1; }
| directive { $$ = $1; }
;
directive:
T_ARGS expr { $$ = jasm_dir_make_args ($2, $1); }
| T_LOCALS expr { $$ = jasm_dir_make_locals ($2, $1); }
| T_DEFINE T_SYMBOL '=' expr { $$ = jasm_dir_make_define ($2.value, $4, $1); }
;
insns:
insn insns { $1->next = $2; $$ = $1; }
| insn { $$ = $1; }
;
insn:
T_MNEMONIC operands
{ $$ = jasm_insn_make_generic ($1.tmpl, $2, $1.line_num); }
| T_MNEMONIC { $$ = jasm_insn_make_generic ($1.tmpl, NULL, $1.line_num); }
| T_LABEL { $$ = jasm_insn_make_label ($1.value, $1.line_num); }
;
operands:
expr ',' operands { $$ = jasm_operand_make ($1, $3); }
| expr { $$ = jasm_operand_make ($1, NULL); }
;
expr:
T_INTEGER
{ $$ = jasm_expr_make_integer ($1.value, $1.line_num); }
| T_SYMBOL
{ $$ = jasm_expr_make_symbol ($1.value, $1.line_num); }
| expr '+' expr
{ $$ = jasm_expr_make_binop (JASM_EXPR_PLUS, $1, $3, $1->line); }
| expr '-' expr
{ $$ = jasm_expr_make_binop (JASM_EXPR_MINUS, $1, $3, $1->line); }
| '-' expr %prec UNARY
{ $$ = jasm_expr_make_neg ($2, $2->line); }
| '(' expr ')'
{ $$ = $2; }
;
%%
void yyerror (char *msg)
{
extern char *yytext;
jasm_abort ("in line %d: parse error before `%s'\n",
jasm_lex_current_line (), yytext);
}
JasmMethod *
jasm_parse ()
{
yyparse ();
return program;
}