123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- %{
- /*
- * Copyright (C) 2006-2010 Michael Buesch <m@bues.ch>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include "parser.h"
- #include "main.h"
- #include "util.h"
- #include <stdio.h>
- #include <ctype.h>
- static void interpret_cppinfo(const char *);
- static void update_lineinfo(void);
- static inline void log_current_line(void)
- {
- size_t len;
- len = min(sizeof(cur_lineinfo.linecopy) - 1, strlen(yytext));
- memcpy(cur_lineinfo.linecopy, yytext, len);
- cur_lineinfo.linecopy[len] = '\0';
- }
- %}
- IDENTIFIER ([a-zA-Z_][0-9a-zA-Z_]*)
- WS ([ \t])
- NEWLINE ((\r)|(\n)|(\r\n))
- %%
- ^.*$ { log_current_line(); REJECT; }
- #{WS}+[0-9]+{WS}+\".*\"[0-9 \t]*{NEWLINE} { interpret_cppinfo(yytext); }
- {WS}+ { update_lineinfo(); /* whitespace */ }
- {NEWLINE} { cur_lineinfo.lineno++; update_lineinfo(); }
- ^{WS}*"%"{WS}*arch { update_lineinfo(); return ASM_ARCH; }
- ^{WS}*"%"{WS}*start { update_lineinfo(); return ASM_START; }
- "%"{WS}*assert { update_lineinfo(); return ASM_ASSERT; }
- ^{WS}*\.text{WS}*$ { update_lineinfo(); return SECTION_TEXT; }
- ^{WS}*\.initvals/\({IDENTIFIER}\) { update_lineinfo(); return SECTION_IVALS; }
- spr[0-9a-fA-F]{1,4} { update_lineinfo(); return SPR; }
- r/([0-9]|([1-5][0-9])|(6[0-3])) { update_lineinfo(); return GPR; }
- off/[0-6] { update_lineinfo(); return OFFR; }
- lr/[0-3] { update_lineinfo(); return LR; }
- , { update_lineinfo(); return COMMA; }
- ; { update_lineinfo(); return SEMICOLON; }
- \[ { update_lineinfo(); return BRACK_OPEN; }
- \] { update_lineinfo(); return BRACK_CLOSE; }
- \( { update_lineinfo(); return PAREN_OPEN; }
- \) { update_lineinfo(); return PAREN_CLOSE; }
- == { update_lineinfo(); return EQUAL; }
- != { update_lineinfo(); return NOT_EQUAL; }
- \|\| { update_lineinfo(); return LOGICAL_OR; }
- \&\& { update_lineinfo(); return LOGICAL_AND; }
- \+ { update_lineinfo(); return PLUS; }
- \- { update_lineinfo(); return MINUS; }
- \* { update_lineinfo(); return MULTIPLY; }
- \/ { update_lineinfo(); return DIVIDE; }
- \| { update_lineinfo(); return BITW_OR; }
- \& { update_lineinfo(); return BITW_AND; }
- \^ { update_lineinfo(); return BITW_XOR; }
- \~ { update_lineinfo(); return BITW_NOT; }
- \<\< { update_lineinfo(); return LEFTSHIFT; }
- \>\> { update_lineinfo(); return RIGHTSHIFT; }
- mul { update_lineinfo(); return OP_MUL; }
- add { update_lineinfo(); return OP_ADD; }
- add\. { update_lineinfo(); return OP_ADDSC; }
- addc { update_lineinfo(); return OP_ADDC; }
- addc\. { update_lineinfo(); return OP_ADDSCC; }
- sub { update_lineinfo(); return OP_SUB; }
- sub\. { update_lineinfo(); return OP_SUBSC; }
- subc { update_lineinfo(); return OP_SUBC; }
- subc\. { update_lineinfo(); return OP_SUBSCC; }
- sra { update_lineinfo(); return OP_SRA; }
- or { update_lineinfo(); return OP_OR; }
- and { update_lineinfo(); return OP_AND; }
- xor { update_lineinfo(); return OP_XOR; }
- sr { update_lineinfo(); return OP_SR; }
- srx { update_lineinfo(); return OP_SRX; }
- sl { update_lineinfo(); return OP_SL; }
- rl { update_lineinfo(); return OP_RL; }
- rr { update_lineinfo(); return OP_RR; }
- nand { update_lineinfo(); return OP_NAND; }
- orx { update_lineinfo(); return OP_ORX; }
- mov { update_lineinfo(); return OP_MOV; }
- jmp { update_lineinfo(); return OP_JMP; }
- jand { update_lineinfo(); return OP_JAND; }
- jnand { update_lineinfo(); return OP_JNAND; }
- js { update_lineinfo(); return OP_JS; }
- jns { update_lineinfo(); return OP_JNS; }
- je { update_lineinfo(); return OP_JE; }
- jne { update_lineinfo(); return OP_JNE; }
- jls { update_lineinfo(); return OP_JLS; }
- jges { update_lineinfo(); return OP_JGES; }
- jgs { update_lineinfo(); return OP_JGS; }
- jles { update_lineinfo(); return OP_JLES; }
- jl { update_lineinfo(); return OP_JL; }
- jge { update_lineinfo(); return OP_JGE; }
- jg { update_lineinfo(); return OP_JG; }
- jle { update_lineinfo(); return OP_JLE; }
- jdn { update_lineinfo(); return OP_JDN; }
- jdpz { update_lineinfo(); return OP_JDPZ; }
- jdp { update_lineinfo(); return OP_JDP; }
- jdnz { update_lineinfo(); return OP_JDNZ; }
- jzx { update_lineinfo(); return OP_JZX; }
- jnzx { update_lineinfo(); return OP_JNZX; }
- jext { update_lineinfo(); return OP_JEXT; }
- jnext { update_lineinfo(); return OP_JNEXT; }
- call { update_lineinfo(); return OP_CALL; }
- calls { update_lineinfo(); return OP_CALLS; }
- ret { update_lineinfo(); return OP_RET; }
- rets { update_lineinfo(); return OP_RETS; }
- tkiph { update_lineinfo(); return OP_TKIPH; }
- tkiphs { update_lineinfo(); return OP_TKIPHS; }
- tkipl { update_lineinfo(); return OP_TKIPL; }
- tkipls { update_lineinfo(); return OP_TKIPLS; }
- nap { update_lineinfo(); return OP_NAP; }
- mmio16 { update_lineinfo(); return IVAL_MMIO16; }
- mmio32 { update_lineinfo(); return IVAL_MMIO32; }
- phy { update_lineinfo(); return IVAL_PHY; }
- radio { update_lineinfo(); return IVAL_RADIO; }
- shm16 { update_lineinfo(); return IVAL_SHM16; }
- shm32 { update_lineinfo(); return IVAL_SHM32; }
- tram { update_lineinfo(); return IVAL_TRAM; }
- @[0-9a-fA-F]{1,4} { update_lineinfo(); return RAW_CODE; }
- 0x[0-9a-fA-F]+ { update_lineinfo(); return HEXNUM; }
- -?[0-9]+ { update_lineinfo(); return DECNUM; }
- {IDENTIFIER}: { update_lineinfo(); return LABEL; }
- {IDENTIFIER} { update_lineinfo(); return IDENT; }
- %%
- struct lineinfo cur_lineinfo;
- static inline const char * strip_leading_ws(const char *str)
- {
- while (*str != '\0' && isspace(*str))
- str++;
- return str;
- }
- static void interpret_cppinfo(const char *str)
- {
- const char * const orig = str;
- char tmp[64];
- const char *found;
- char *tail;
- /* This will interpret lines added by CPP.
- * They look like:
- * # lineno "filename" flags...
- */
- str = strip_leading_ws(str);
- if (*str != '#')
- goto error;
- str++; /* skip # character */
- str = strip_leading_ws(str);
- if (*str == '\0')
- goto error;
- /* Line number */
- found = strchr(str, ' ');
- if (!found)
- goto error;
- memset(tmp, 0, sizeof(tmp));
- memcpy(tmp, str, min(sizeof(tmp) - 1, (size_t)(found - str)));
- cur_lineinfo.lineno = strtoul(tmp, &tail, 0);
- if (*tail != '\0')
- goto error;
- str = strip_leading_ws(found);
- /* File name */
- if (*str != '\"')
- goto error;
- str++;
- if (*str == '\0')
- goto error;
- found = strchr(str, '\"');
- if (!found)
- goto error;
- memset(cur_lineinfo.file, 0, sizeof(cur_lineinfo.file));
- memcpy(cur_lineinfo.file, str, min(sizeof(cur_lineinfo.file) - 1,
- (size_t)(found - str)));
- /* We ignore the flags. */
- return;
- error:
- fprintf(stderr, "Invalid CPP line directive: %s\n", orig);
- exit(1);
- }
- static void update_lineinfo(void)
- {
- int i = 0;
- while (yytext[i] != '\0') {
- switch (yytext[i]) {
- case '\r':
- case '\n':
- cur_lineinfo.column = 0;
- break;
- case '\t':
- cur_lineinfo.column += 8 - (cur_lineinfo.column % 8);
- break;
- default:
- cur_lineinfo.column++;
- }
- i++;
- }
- }
|