Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Match flags. */
- #define M_NI 0 /* Unconditionally not increment. */
- #define M_I 1 /* Unconditionally increment. */
- #define M_IC 2 /* Increment conditionally (if true.) */
- #define M_NS 1 /* Not suppress error msgs. */
- #define M_S 0 /* Suppress error messages. */
- /**
- *
- */
- static inline void skip_whitespace(char **s)
- {
- char *p = *s;
- while (isblank(*p))
- p++;
- *s = p;
- }
- /**
- *
- */
- static inline int match(char **s, char c, int inc, int supr)
- {
- int ret = 0;
- char *p = *s;
- if (tolower(*p) == c)
- ret = 1;
- else
- {
- if (supr)
- fprintf(stderr, "file.c:%d: Error: expected '%c', found '%c'\n",
- current_line, c, *p);
- }
- /* Increment. */
- if (inc == M_I)
- *s = p + 1;
- else if (inc == M_IC && ret)
- *s = p + 1;
- return (ret);
- }
- /**
- *
- */
- static inline int match_lt(char **s, char c, int inc, int supr)
- {
- int ret = 0;
- char *p = *s;
- if (*p < c)
- ret = 1;
- else
- {
- if (supr)
- fprintf(stderr, "file.c:%d: Error: expected '%c' < '%c'\n",
- current_line, c, *p);
- }
- if (inc == M_I)
- *s = p + 1;
- else if (inc == M_IC && ret)
- *s = p + 1;
- return (ret);
- }
- /**
- *
- */
- static inline int match_gt(char **s, char c, int inc, int supr)
- {
- int ret = 0;
- char *p = *s;
- if (*p > c)
- ret = 1;
- else
- {
- if (supr)
- fprintf(stderr, "file.c:%d: Error: expected '%c' > '%c'\n",
- current_line, c, *p);
- }
- if (inc == M_I)
- *s = p + 1;
- else if (inc == M_IC && ret)
- *s = p + 1;
- return (ret);
- }
- /**
- *
- */
- static inline long read_number(char **s)
- {
- long number;
- char *nptr = NULL;
- char *p = *s;
- number = strtol(p, &nptr, 0);
- if (p != nptr && errno == 0)
- {
- *s = nptr;
- return (number);
- }
- fprintf(stderr, "file.c:%d: Error: invalid number\n",
- current_line);
- return (LONG_MAX);
- }
- /**
- *
- */
- static int read_first_operand(char **insn, struct insn_tbl *tbl)
- {
- if (!match(insn, 'r', M_I, M_NS))
- goto err;
- if (match_lt(insn, '0', M_NI, M_S) ||
- match_gt(insn, '7', M_I, M_S))
- {
- goto err;
- }
- return (1);
- err:
- fprintf(stderr, "file.c:%d: Error: first operand of instruction"
- " '%s' is invalid!\n", current_line, tbl->name);
- return (0);
- }
- /**
- *
- */
- static int read_second_operand(char **insn, struct insn_tbl *tbl)
- {
- long imm;
- if (!match(insn, ',', M_I, M_NS))
- goto err;
- skip_whitespace(insn);
- /* If Reg/Reg. */
- if (match(insn, 'r', M_IC, M_S))
- {
- if (match_lt(insn, '0', M_NI, M_S) || match_gt(insn, '7', M_I, M_S))
- goto err;
- skip_whitespace(insn);
- if (!match(insn, '#', M_NI, M_S) && !match(insn, ';', M_IC, M_S) &&
- !match(insn, '\n', M_NI, M_S) && !match(insn, '\0', M_NI, M_S))
- {
- goto err;
- }
- }
- /* Reg/Imm. */
- else
- {
- imm = read_number(insn);
- if (imm == LONG_MAX)
- goto err;
- skip_whitespace(insn);
- if (!match(insn, '#', M_NI, M_S) && !match(insn, ';', M_IC, M_S) &&
- !match(insn, '\n', M_NI, M_S) && !match(insn, '\0', M_NI, M_S))
- {
- goto err;
- }
- printf("num: %ld\n", imm);
- }
- return (1);
- err:
- fprintf(stderr, "file.c:%d: Error: second operand of instruction"
- " '%s' is invalid!\n", current_line, tbl->name);
- return (0);
- }
- /**
- *
- */
- static int insn_two_params(char **insn, struct insn_tbl *tbl)
- {
- long number;
- char *nptr = NULL;
- char *p = *insn;
- if (!read_first_operand(&p, tbl))
- return (-1);
- skip_whitespace(&p);
- if (!read_second_operand(&p, tbl))
- return (-1);
- /* Update the pointer. */
- *insn = p;
- return (0);
- }
Add Comment
Please, Sign In to add comment