mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2025-01-01 14:33:35 +01:00
118 lines
2 KiB
Text
118 lines
2 KiB
Text
|
%{
|
||
|
#include <fxos.h>
|
||
|
#include <errors.h>
|
||
|
#include <util.h>
|
||
|
|
||
|
/* Values for tokens generated by the lexer */
|
||
|
static union {
|
||
|
char *text;
|
||
|
long long integer;
|
||
|
} yylval;
|
||
|
|
||
|
/* Token list */
|
||
|
#define NUMBER 0
|
||
|
#define SYMBOL 1
|
||
|
|
||
|
%}
|
||
|
|
||
|
%option prefix="reg"
|
||
|
%option noyywrap
|
||
|
%option nounput
|
||
|
|
||
|
decimal 0|[1-9][0-9]*
|
||
|
octal 0[0-7]+
|
||
|
hexa 0x[0-9a-fA-F]+
|
||
|
number {decimal}|{octal}|{hexa}
|
||
|
|
||
|
symbol [^0-9 \t\n][^\n]*
|
||
|
|
||
|
space [ \t]+
|
||
|
|
||
|
%%
|
||
|
|
||
|
^#[^\n]* ;
|
||
|
{space} ;
|
||
|
[\n] yylineno++;
|
||
|
|
||
|
{number} { yylval.integer = integer(yytext, NULL); return NUMBER; }
|
||
|
{symbol} { yylval.text = strdup(yytext); return SYMBOL; }
|
||
|
|
||
|
<<EOF>> return -1;
|
||
|
|
||
|
%%
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
/* lex_reg(): Peripheral register table lexer and parser */
|
||
|
struct reg_address *lex_reg(void *data, size_t len, int *count)
|
||
|
{
|
||
|
/* Count number of register descriptions (upper bound) */
|
||
|
|
||
|
YY_BUFFER_STATE buf = yy_scan_bytes(data, len);
|
||
|
yylineno = 1;
|
||
|
|
||
|
int total = 0, t;
|
||
|
while((t = yylex()) != -1)
|
||
|
{
|
||
|
total += (t == NUMBER);
|
||
|
if(t == SYMBOL) free(yylval.text);
|
||
|
}
|
||
|
|
||
|
yy_delete_buffer(buf);
|
||
|
|
||
|
/* Allocate a large enough register array */
|
||
|
|
||
|
struct reg_address *table = calloc(total, sizeof *table);
|
||
|
if(!table)
|
||
|
{
|
||
|
errf(ERR_ERRNO, "cannot allocate memory for database");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* Lex all instructions and fill in the array */
|
||
|
|
||
|
buf = yy_scan_bytes(data, len);
|
||
|
yylineno = 1;
|
||
|
|
||
|
struct reg_address *reg = table - 1;
|
||
|
int line = -1;
|
||
|
|
||
|
while(1)
|
||
|
{
|
||
|
t = yylex();
|
||
|
|
||
|
if(t == NUMBER || t == -1)
|
||
|
{
|
||
|
/* Finalize current instruction */
|
||
|
if(reg >= table && !reg->name)
|
||
|
err("%d: unnamed register", line);
|
||
|
else reg++;
|
||
|
}
|
||
|
if(t == -1) break;
|
||
|
|
||
|
if(t == NUMBER)
|
||
|
{
|
||
|
reg->address = yylval.integer;
|
||
|
line = yylineno;
|
||
|
}
|
||
|
else if(t == SYMBOL && reg < table)
|
||
|
{
|
||
|
err("%d: expected register address", yylineno);
|
||
|
free(yylval.text);
|
||
|
}
|
||
|
else if(t == SYMBOL && !reg->name)
|
||
|
{
|
||
|
reg->name = yylval.text;
|
||
|
}
|
||
|
else if(t == SYMBOL)
|
||
|
{
|
||
|
err("%d: excess names for 0x%08x\n", reg->address);
|
||
|
free(yylval.text);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
yy_delete_buffer(buf);
|
||
|
if(count) *count = reg - table;
|
||
|
return table;
|
||
|
}
|