📄 parse.c
字号:
#include "i_attribute.h"#include "a64-2.h"#include "parse.h"#include "error.h"#include "opcode.h"#include "iob.h"#include "label.h"#include <stdio.h>static char err_msg[80];static kw_id_t keyword_id = 0;void print_ekey();static errno_t parse_keyword(char *s);static errno_t parse_label(char *s);static struct return_struct do_parse_transfer(char *s, i_key_t *i_key);errno_t analyse_line(line_info_t *line_info, e_key_t *e_key, char *s) { errno_t errno = 0; char str[80]; int i = 0; unsigned char c = 0; if (!s || !s[0]) return ERR_LINE; char *p = s; /* i_key link */ i_key_t *i_key = 0; ops_attr_t ops_attr = { 0, 0, 0 }; while (*p && ((*p == ' ') || (*p == KEY_TAB))) p++; /* skip space or TAB */ while (*p && ((*p != ' ') && (*p != KEY_TAB))) str[i++] = *p++; str[i] = 0; if (c = get_prefixid(str)) { /* this is a instruction prefix */ e_key->i_prefix = (prefix_t*)a64_malloc(sizeof(prefix_t)); e_key->i_prefix->lock = c == 0xf0 ? c : 0; e_key->i_prefix->rep = c != 0xf0 ? c : 0; i = 0; while (*p && ((*p == ' ') || (*p == KEY_TAB))) p++; /* skip ' ' */ /* get next instruction string */ while (*p && ((*p != ' ') && (*p != KEY_TAB))) str[i++] = *p++; str[i] = 0; } /* found instruction set */ if (!(i_key = (i_key_t *)get_ins(str))) { mount_err_link(ERR_INS, line_errmsg, 0); return ERR_INS; } if (c) { if (c == 0xf0) { /* it's lock prefix */ /* do nothing */ } else if (!is_string_ins(i_key)) { /* it's rep prefix */ /* example: rep movsb */ sprintf(err_msg, "at %d: invalid instruction \n", line); mount_err_link(0, 0, err_msg); return ERR_INS; } }next: /* found instruction */ e_key->ops_key = (ops_key_t *)a64_malloc(sizeof(ops_key_t)); errno |= get_ops_key(e_key->ops_key, p); /* check operands valid ??? */ if (!check_ops_key(e_key->ops_key)) { sprintf(err_msg, "at %d: %s\n", line, "check operands error, it's invalid operands"); mount_err_link(0, 0, err_msg); return ERR_OPERAND; } get_ops_attr(&ops_attr, e_key->ops_key); o_key_t *so_key = e_key->ops_key->so_key; o_key_t *do_key = e_key->ops_key->do_key; mem_t *mem = so_key && so_key->mem ? so_key->mem : do_key && do_key->mem ? do_key->mem : 0; if (mem) { if (mem->transfer_cast) { if (((i_key == CALL) || (i_key == JMP)) && so_key->mem) ops_attr.so_attr |= FAR_POINTER; else { sprintf(err_msg, "error at %d: error cast\n", line); mount_err_link(0, 0, err_msg); return ERR_ERROR; } } } if (!(e_key->i_key = get_i_key(i_key, &ops_attr))) { sprintf(err_msg, "at %d: %s\n", line, "invalid instruction or operands"); mount_err_link(0, 0, err_msg); return ERR_INS; } /* check the instruct in current bits is valid ??? */ if (is_ONLY_IN_BITS(e_key->i_key->i_attr)) { if (get_ONLY_BITS(e_key->i_key->i_attr) != current_bits) { sprintf(err_msg, "error at %d: %s\n", line, "instruct in current bits invalid"); mount_err_link(0, 0, err_msg); return ERR_INS; } } e_key->bits = current_bits; return errno;}/********************************************************/static struct return_struct pre_analyse_line(char *s){ struct return_struct ret = { E_OK, s }; if (!s) return ret; char *p = s; int i = 0; char str[80]; errno_t errno = 0; for ( ; ; p++) { if (is_c(*p) || is_n(*p) || *p == '_') { str[i++] = *p; } else switch (*p) { case 0 : str[i] = 0; if (ret.code == E_LABEL && i == 0) { sprintf(err_msg, "error at %d: %s\n", line, "label string error"); mount_err_link(0, 0, err_msg); ret.code == E_ERROR; return ret; } else if (ret.code == E_KEYWORD && (i == 0)) { ret.code = E_ERROR; } else if (ret.code == E_NEED_CONON || ((ret.code == E_LABEL) && i)) { sprintf(err_msg, "error at %d: %s\n", line, "label loss ':'"); mount_err_link(0, 0, err_msg); ret.code = E_ERROR; return ret; } else if (ret.code == E_OK && i) { /* keep E_OK for next step */ if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; ret.ptr += i; } } else if (((ret.code == E_BLANK) || (ret.code == E_TAB)) && i) { /** reserved for E_KEYWORD */ if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; ret.ptr += i; } else { ret.code = E_OK; ret.ptr = s; } } else ret.code = E_NEW_LINE; goto do_parse_error; case ' ': case KEY_TAB: if (i) { str[i] = 0; if (ret.code == E_KEYWORD) { if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; ret.ptr += i; } else ret.code = E_ERROR; goto do_parse_error; } else if ((ret.code == E_TAB) || (ret.code == E_BLANK)) { i_key_t *i_key; /* it's keyword ??? */ if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; /* skip keyword string */ ret.ptr += i; } else if (i_key=get_transfer_ins(str)) { ret.ptr = p + 1; ret = do_parse_transfer( ret.ptr,i_key); if (ret.code == E_OK) ret.ptr = s; } else ret.code = E_OK; goto do_parse_error; } else if (ret.code == E_LABEL) { /* it's label string */ /* next step do by E_CONON */ ret.code = E_NEED_CONON; i = 0; } else if (ret.code == E_NEED_CONON) { sprintf(err_msg, "error at %d: %s \n", line, "label loss ':'"); mount_err_link(0, 0, err_msg); ret.code = E_ERROR; return ret; } else if (ret.code == E_CONON) { /* parse label... next step to do parse line.... */ i_key_t *i_key = 0; if (i_key = get_transfer_ins(str)) { ret.ptr = p + 1; ret = do_parse_transfer( ret.ptr, i_key); if (ret.code == E_OK) ret.ptr = s; } else { ret.code = E_OK; } goto do_parse_error; } else if (ret.code == E_BLANK) { if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; ret.ptr += i; } else ret.code = E_OK; goto do_parse_error; } else if (ret.code == E_OK) { i_key_t *i_key = 0; if (keyword_id = get_keyword(str)) { ret.code = E_KEYWORD; ret.ptr += i; } else if (i_key=get_transfer_ins(str)) { ret.ptr = p + 1; ret = do_parse_transfer( ret.ptr, i_key); if (ret.code == E_OK) ret.ptr = s; } /* next step to do parse line... */ goto do_parse_error; } /* it's blank string...... */ } else { if (ret.code == E_KEYWORD) { /* it's keyword */ /* it's allow ". xxxx" */ break; } else if (ret.code == E_LABEL) { /* it's error */ sprintf(err_msg, "error at %d: %s\n", line, "the label is error"); mount_err_link(0, 0, err_msg); ret.code = E_ERROR; goto do_parse_error; } else if (ret.code == E_CONON) { if (*p == ' ') ret.code = E_BLANK; else ret.code = E_TAB; ret.ptr = p + 1; } else if (ret.code == E_NEED_CONON) { /* keep the flag for label */ } else { if (*p == ' ') ret.code = E_BLANK; else if (*p == KEY_TAB) ret.code = E_TAB; } } ret.ptr = p + 1; break; case '.': /* it's a keyword */ if (i || ret.code == E_KEYWORD || ret.code == E_LABEL || ret.code == E_CONON) { ret.code = E_ERROR; goto do_parse_error; } ret.code = E_KEYWORD; ret.ptr = p + 1; i = 0; break; case '@': /* it's a label */ if(i || ret.code == E_KEYWORD || ret.code == E_LABEL || ret.code == E_CONON) { ret.code = E_ERROR; goto do_parse_error; } ret.code = E_LABEL; ret.ptr = p + 1; i = 0; break; case ':': if ((ret.code != E_LABEL) && (ret.code != E_NEED_CONON)) { ret.code = E_ERROR; goto do_parse_error; } if (ret.code != E_NEED_CONON) str[i] = 0; if (errno = parse_label(str)) { mount_err_link(E_LABEL, line_errmsg, 0); ret.code = E_ERROR; return ret; } ret.code = E_CONON; ret.ptr = p + 1; i = 0; break; case '!': /* it's a comment */ ret.code = E_COMMENT; return ret; case '\n': /* new line */ ret.code = E_NEW_LINE; goto do_parse_error; default: ret.code = E_ERROR; goto do_parse_error; } }do_parse_error: if (ret.code == E_ERROR) { sprintf(err_msg, "error at line %d: %s '%c'\n", line, "parse error at ", *p); mount_err_link(0, 0, err_msg); } return ret;}/*************************************************************/static errno_t parse_label(char *s){ errno_t errno = 0; if (!is_label(s)) mount_label_table(s); else errno = E_LABEL; return errno;}static struct return_struct do_parse_transfer(char *p, i_key_t *i_key){ struct return_struct ret = { 0, p }; int i = 0; char str[80]; while (*p && (*p == ' ' || *p == KEY_TAB)) p++; if (*p == '@') { p++; while (*p && *p != ' ' && *p != KEY_TAB) str[i++] = *p++; str[i] = 0; mount_hole_link(str, i_key); ret.code = E_NEW_LINE; } else { /* this is a memory operand example: jmp [ecx] */ ret.code = E_OK; } return ret;}/*************************************************************/static errno_t parse_keyword(char *s){ errno_t errno = 0; char *p = s; int i = 0; char str[80]; while (*p && (*p == ' '|| *p == KEY_TAB)) p++; while (*p && *p != ' ' && *p != KEY_TAB) str[i++] = *p++; str[i] = 0; while (*p && (*p == ' ' || *p == KEY_TAB)) p++; switch (keyword_id) { case KW_MODE: current_mode = get_modeid(str); if (!current_mode || *p) { sprintf(err_msg, "error at %d: mode value error\n", line); mount_err_link(0, 0, err_msg); return ERR_ERROR; } break; case KW_BITS: current_bits = get_bitsid(str); if (!current_bits || *p) { sprintf(err_msg, "error at %d: bits value error\n", line); mount_err_link(0, 0, err_msg); return ERR_ERROR; } break; case KW_FUNCTION: /* it's function */ break; case KW_VAR: break; case KW_CONST: break; case KW_CODE: break; case KW_TEXT: break; case KW_BYTE: break; case KW_WORD: break; case KW_DWORD: break; case KW_QWORD: break; case KW_MACRO: break; case KW_PTR: break; } return errno;}/*********************************************************************//*static proceed_parse_keyword(char *s){}*//************************************************************************ function: analyse_file() paramter: void: return value: errno if error ************************************************************************/errno_t analyse_file(struct iob *iob){ errno_t errno = 0; struct return_struct ret = { E_OK, 0 }; char linebuf[LINE_SIZE]; char err_msg[80]; e_key_t *head_e_key = e_key_link; line_info_t line_info = { 0, 0 }; /* parse file */ while (read_into_iob(iob, sizeof(iob->buf))) { /* parse line */ while (readln_from_iob(iob, linebuf)) { line++; ret = pre_analyse_line(linebuf); if (ret.code == E_ERROR) { return ERR_OPERAND; } else if (ret.code == E_KEYWORD) { errno = parse_keyword(ret.ptr); if (errno) return ERR_OPERAND; // goto do_analyse_file_error; continue; } else if (ret.code == E_BLANK) { } else if (ret.code == E_NEW_LINE) { } else if (ret.code == E_COMMENT) { } else if (ret.code == E_OK) { e_key_t *p = (e_key_t *)a64_malloc(sizeof(e_key_t)); p->line = line; errno = analyse_line(&line_info, p, ret.ptr); if (errno) return errno; if (!head_e_key) { head_e_key = p; e_key_link = p; /* global e_key link */ } else { while (head_e_key->next) head_e_key = head_e_key->next; head_e_key->next = p; } } /* next line .... */ } }do_analyse_file_error: return errno;}/************************************************************************/void print_ekey(){ e_key_t *e_key = e_key_link; while (e_key) { #if 0 puts("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); if (e_key->ops_key) print_ops(e_key->ops_key); if (e_key->i_key) { printf("---i_attr: %x\n", e_key->i_key->i_attr); printf("---opcode:%x\n", e_key->i_key->opcode); } if (e_key->i_prefix) { printf("---lock: %x\n" ,e_key->i_prefix->lock); printf("---rep: %x\n", e_key->i_prefix->rep); } puts("#############################");#endif printf("e_key line is %d\n", e_key->line); e_key = e_key->next; }}/*char *testfile = "test.s";#include <fcntl.h>int main(){ struct iob riob, wiob; int fd = open(testfile, O_RDONLY); int fdw = open("kkk", O_CREAT); init_iob(fd, &riob); init_iob(fdw, &wiob); char *e_buf = (char *)malloc(512); errno_t errno = 0; int i = 0; errno = analyse_file(&riob); if (errno) { printf("%d\n",current_mode); print_err(); exit(1); } if (errno = generate(&wiob)) { print_err(); release_resource(); exit(1); } flush_all_iob(&wiob);#ifdef DEBUG_PRINT_CODE while(i<current_pc) printf("%x ",(unsigned char)wiob.buf[i++]); puts(""); #endif release_resource(); close(fd); close(fdw); return 0;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -