nexmon – Rev 1
?pathlinks?
%{
/*
* 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; }
srxh { update_lineinfo(); return OP_SRXH; }
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; }
orxh { update_lineinfo(); return OP_ORXH; }
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; }
jboh { update_lineinfo(); return OP_JBOH; }
jnboh { update_lineinfo(); return OP_JNBOH; }
jzx { update_lineinfo(); return OP_JZX; }
jzxh { update_lineinfo(); return OP_JZXH; }
jnzx { update_lineinfo(); return OP_JNZX; }
jnzxh { update_lineinfo(); return OP_JNZXH; }
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; }
nap2 { update_lineinfo(); return OP_NAP2; }
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++;
}
}