Rizin
unix-like reverse engineering framework and cli tools
rlcc.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 /* Radare Language Code Compiler */
5 
6 #include <mpc.h>
7 #define eprintf(x, y...) fprintf(stderr, x, ##y)
8 
9 static int isComment(mpc_ast_t *node) {
10  if (!strcmp(node->tag, "comment|regex")) {
11  return 1;
12  }
13  if (!strcmp(node->tag, "linecomment|regex")) {
14  return 1;
15  }
16  return 0;
17 }
18 
19 static int isInlineAssembly(mpc_ast_t *node) {
20  if (!strcmp(node->tag, "asm|regex")) {
21  return 1;
22  }
23  return 0;
24 }
25 
26 static int isStatement(mpc_ast_t *node) {
27  if (!strcmp(node->tag, "stmt|>")) {
28  return 1;
29  }
30  return 0;
31 }
32 
33 static int isSigdef(mpc_ast_t *node) {
34  if (!strcmp(node->tag, "sigdef|>")) {
35  return 1;
36  }
37  return 0;
38 }
39 
40 static int isProcedure(mpc_ast_t *node) {
41  if (!strcmp(node->tag, "procedure|>")) {
42  return 1;
43  }
44  return 0;
45 }
46 
47 static void processNode(mpc_ast_t *node) {
48  if (isStatement(node)) {
49  int i, narg = 0;
50  const char *args[32];
51  for (i = 0; i < node->children_num; i++) {
52  const char *tag = node->children[i]->tag;
53  const char *val = node->children[i]->contents;
54  if (strcmp(tag, "char")) {
55  printf("TAG (%s) = (%s)\n", tag, val);
56  args[narg++] = val;
57  }
58  }
59  printf("; CALL WITH %d ARGS\n", narg);
60  } else if (isProcedure(node)) {
61  int i, j;
62  const char *name = node->children[0]->contents;
63  printf("%s:\n", name);
64  for (i = 0; i < node->children_num; i++) {
65  if (!strcmp(node->children[i]->tag, "body|>")) {
66  node = node->children[i];
67  for (i = 0; i < node->children_num; i++) {
68  if (!strcmp(node->children[i]->tag, "stmt|>")) {
69  processNode(node->children[i]);
70  } else {
71  eprintf("UNK %s\n", node->children[i]->tag);
72  }
73  }
74  break;
75  }
76  }
77  } else if (isSigdef(node)) {
78  if (node->children_num > 4) {
79  const char *name = node->children[0]->contents;
80  const char *type = node->children[2]->contents;
81  const char *size = node->children[4]->contents;
82  if (!strcmp(type, "alias")) {
83  printf(".equ %s,%s\n", name, size);
84  } else if (!strcmp(type, "syscall")) {
85  printf("; TODO: register syscall %s number %s\n", name, size);
86  } else if (!strcmp(type, "global")) {
87  printf("; TODO: global \n");
88  } else {
89  printf("; UNKNOWN EXPRESISON: NAME = '%s' ", name);
90  printf("TYPE = '%s' ", type);
91  printf("SIZE = '%s'\n", size);
92  }
93  }
94  } else if (isComment(node)) {
95  char *s = strdup(node->contents + 2);
96  int len = strlen(s);
97  if (node->contents[1] == '*') {
98  s[len - 2] = 0;
99  }
100  while (s) {
101  char *nl = strchr(s, '\n');
102  if (nl) {
103  *nl = 0;
104  printf("; %s\n", s);
105  s = nl + 1;
106  } else {
107  printf("; %s\n", s);
108  s = NULL;
109  }
110  }
111  free(s);
112  } else if (isInlineAssembly(node)) {
113  printf("%s\n", node->contents + 1);
114  }
115 }
116 
117 int main(int argc, char **argv) {
118  mpc_parser_t *Ident = mpc_new("ident");
119  mpc_parser_t *Number = mpc_new("number");
120  mpc_parser_t *Character = mpc_new("character");
121  mpc_parser_t *String = mpc_new("string");
122  mpc_parser_t *Factor = mpc_new("factor");
123  mpc_parser_t *Term = mpc_new("term");
124  mpc_parser_t *Lexp = mpc_new("lexp");
125  mpc_parser_t *Stmt = mpc_new("stmt");
126  mpc_parser_t *Exp = mpc_new("exp");
127  mpc_parser_t *Vartype = mpc_new("vartype");
128  mpc_parser_t *Typeident = mpc_new("typeident");
129  mpc_parser_t *Decls = mpc_new("decls");
130  mpc_parser_t *Args = mpc_new("args");
131  mpc_parser_t *Body = mpc_new("body");
132  mpc_parser_t *Comment = mpc_new("comment");
133  mpc_parser_t *Linecomment = mpc_new("linecomment");
134  mpc_parser_t *Asm = mpc_new("asm");
135  mpc_parser_t *Procedure = mpc_new("procedure");
136  mpc_parser_t *CProcedure = mpc_new("cprocedure");
137  mpc_parser_t *Sigdef = mpc_new("sigdef");
138  mpc_parser_t *Sigbody = mpc_new("sigbody");
139  mpc_parser_t *Includes = mpc_new("includes");
140  mpc_parser_t *Smallc = mpc_new("smallc");
141 
143  " ident : /[a-zA-Z_][a-zA-Z0-9_]*/ ; \n"
144  " number : /[0-9]+/ ; \n"
145  " character : /'.'/ ; \n"
146  " string : /\"(\\\\.|[^\"])*\"/ ; \n"
147  " \n"
148  " factor : '(' <lexp> ')' \n"
149  " | <number> \n"
150  " | <character> \n"
151  " | <string> \n"
152  " | <ident> '(' <lexp>? (',' <lexp>)* ')' \n"
153  " | <ident> ; \n"
154  " \n"
155  " term : <factor> (('*' | '/' | '%') <factor>)* ; \n"
156  " lexp : <term> (('+' | '-') <term>)* ; \n"
157  " \n"
158  " stmt : '{' <stmt>* '}' \n"
159  " | \"while\" '(' <exp> ')' <stmt> \n"
160  " | \"if\" '(' <exp> ')' <stmt> \n"
161  " | <ident> '=' <lexp> ';' \n"
162  " | \"print\" '(' <lexp>? ')' ';' \n"
163  " | \"return\" <lexp>? ';' \n"
164  " | <ident> '(' (<number>|<ident>|<string>)? (',' (<string>|<number>|<ident>))* ')' ';' ; \n"
165  " \n"
166  " exp : <lexp> '>' <lexp> \n"
167  " | <lexp> '<' <lexp> \n"
168  " | <lexp> \">=\" <lexp> \n"
169  " | <lexp> \"<=\" <lexp> \n"
170  " | <lexp> \"!=\" <lexp> \n"
171  " | <lexp> \"==\" <lexp> ; \n"
172  " \n"
173  " vartype : (\"int\" | \"char\") ; \n"
174  " typeident : <vartype> <ident> ; \n"
175  " decls : (<typeident> ';')* ; \n"
176  " args : <typeident>? (',' <typeident>)* ; \n"
177  " body : '{' <decls> <stmt>* '}' ; \n"
178  " comment : /\\/\\*([^\\*])*\\*\\// ; \n"
179  " linecomment : /\\/\\/([^\\n])*/ ; \n"
180  " asm : /\\:([^\\n])*/ ; \n"
181  " procedure : <ident> '@' \"global\" '(' <number>? ')' <body> ; \n"
182  " cprocedure : <vartype> <ident> '(' <args> ')' <body> ; \n"
183  " sigdef : <ident> '@' <ident> '(' <number> ')' ';' ; \n"
184  " sigbody : '@' <ident> '(' <number> ')' ';' ; \n"
185  " includes : (\"#include\" <string>)* ; \n"
186  " smallc : /^/ (<comment>|<asm>|<linecomment>|<sigdef>|<sigbody>|<procedure>|<cprocedure>)* <includes> <decls> /$/ ; \n",
187  Ident, Number, Character, String, Factor, Term, Lexp, Stmt, Exp,
188  Vartype, Typeident, Decls, Args, Body, Comment, Linecomment, Asm, Procedure, CProcedure,
189  Sigdef, Sigbody, Includes, Smallc, NULL);
190 
191  if (err != NULL) {
194  return -1;
195  }
196 
197 #if 1
198  if (argc > 1) {
199 
200  mpc_result_t r;
201  if (mpc_parse_contents(argv[1], Smallc, &r)) {
202  mpc_ast_print_to(r.output, stderr);
203  {
204  int i;
205  mpc_ast_t *root = r.output;
206  for (i = 0; i < root->children_num; i++) {
207  mpc_ast_t *node = root->children[i];
208  eprintf("; TAG = %s (%s)\n", node->tag, node->contents);
209  processNode(node);
210  }
211  }
212  mpc_ast_delete(r.output);
213  } else {
214  mpc_err_print(r.error);
215  mpc_err_delete(r.error);
216  }
217 
218  } else {
219 
220  mpc_result_t r;
221  if (mpc_parse_pipe("<stdin>", stdin, Smallc, &r)) {
222  mpc_ast_print(r.output);
223  mpc_ast_delete(r.output);
224  } else {
225  mpc_err_print(r.error);
226  mpc_err_delete(r.error);
227  }
228  }
229 #endif
230 
231  mpc_cleanup(17, Ident, Number, Character, String, Factor, Term, Lexp, Stmt, Exp,
232  Vartype, Typeident, Decls, Args, Body, Comment, Procedure, CProcedure,
233  Sigdef, Includes, Smallc);
234 
235  return 0;
236 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
static bool err
Definition: armass.c:435
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
int root
Definition: enough.c:226
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int args
Definition: mipsasm.c:18
int type
Definition: mipsasm.c:17
mpc_err_t * mpca_lang(int flags, const char *language,...)
Definition: mpc.c:3790
void mpc_ast_delete(mpc_ast_t *a)
Definition: mpc.c:2886
int mpc_parse_pipe(const char *filename, FILE *pipe, mpc_parser_t *p, mpc_result_t *r)
Definition: mpc.c:1345
void mpc_err_print(mpc_err_t *x)
Definition: mpc.c:584
void mpc_ast_print(mpc_ast_t *a)
Definition: mpc.c:3036
int mpc_parse_contents(const char *filename, mpc_parser_t *p, mpc_result_t *r)
Definition: mpc.c:1353
mpc_parser_t * mpc_new(const char *name)
Definition: mpc.c:1480
void mpc_ast_print_to(mpc_ast_t *a, FILE *fp)
Definition: mpc.c:3040
void mpc_cleanup(int n,...)
Definition: mpc.c:1596
void mpc_err_delete(mpc_err_t *x)
Definition: mpc.c:575
@ MPCA_LANG_DEFAULT
Definition: mpc.h:355
#define eprintf(x, y...)
Definition: rlcc.c:7
int main(int argc, char **argv)
Definition: rlcc.c:117
static int isComment(mpc_ast_t *node)
Definition: rlcc.c:9
static void processNode(mpc_ast_t *node)
Definition: rlcc.c:47
static int isInlineAssembly(mpc_ast_t *node)
Definition: rlcc.c:19
static int isStatement(mpc_ast_t *node)
Definition: rlcc.c:26
static int isSigdef(mpc_ast_t *node)
Definition: rlcc.c:33
static int isProcedure(mpc_ast_t *node)
Definition: rlcc.c:40
static RzSocket * s
Definition: rtr.c:28
Definition: mpc.h:284
int children_num
Definition: mpc.h:288
char * tag
Definition: mpc.h:285
struct mpc_ast_t ** children
Definition: mpc.h:289
char * contents
Definition: mpc.h:286
Definition: mpc.h:40
Definition: z80asm.h:102