URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zpp.l] - Rev 13
Go to most recent revision | Compare with Previous | Blame | View Log
/*******************************************************************************
**
** Filename: zpp.l
**
** Project: Zip CPU -- a small, lightweight, RISC CPU core
**
** Purpose: The preprocessor for the Zip Assembler.
**
** This routine strips comments, handles #define's, #ifdef's, and
** #include statements in a C fashion.
**
** #define macro's are also defined in the language and therefore
** supposed to be supported, but the support isn't there yet.
**
** Creator: Dan Gisselquist, Ph.D.
** Gisselquist Tecnology, LLC
**
********************************************************************************
**
** Copyright (C) 2015, Gisselquist Technology, LLC
**
** This program is free software (firmware): you can redistribute it and/or
** modify it under the terms of the GNU General Public License as published
** by the Free Software Foundation, either version 3 of the License, or (at
** your option) any later version.
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
** for more details.
**
** You should have received a copy of the GNU General Public License along
** with this program. (It's in the $(ROOT)/doc directory, run make with no
** target there if the PDF file isn't present.) If not, see
** <http://www.gnu.org/licenses/> for a copy.
**
** License: GPL, v3, as defined and found on www.gnu.org,
** http://www.gnu.org/licenses/gpl.html
**
**
*******************************************************************************/
%{
// #include <FlexLexer.h>
#include <string>
#include <ctype.h>
#include <stdio.h>
#include <list>
using namespace std;
extern "C" int yylex();
// #include "zprepr.tab.h"
int ndef = 0;
void stb_define(const char *str);
void stb_args(const char *str);
void stb_macro(const char *value);
void stb_addmacro(const char *value);
bool stb_isdefined(const char *str);
const char *stb_getdefn(const char *str);
%}
%x DEF DFA DFV INDEF IFDEFV INNOTDEF NODEF NVRDEF COMMENT
%x INDEF_EOL INNOTDEF_EOL
%option noyywrap
%option stack
ID [_:A-Za-z][_:A-Za-z0-9]*
%%
<COMMENT>"*/" { yy_pop_state(); }
<COMMENT>[^*]+ { /* Ignore comments */ }
<COMMENT>"*"+[^/] { /* Ignore comments */ }
<INITIAL,INDEF>^"#include"[ \t]+\"[^\"]+\" {
char *ptr = &yytext[9], *start, *end, *str;
while(isspace(*ptr))
ptr++;
start = ptr;
ptr++;
while((*ptr)&&(*ptr != '\"'))
ptr++;
*ptr = '\0';
yypush_buffer_state(yy_create_buffer(
fopen(start, "r"),
YY_BUF_SIZE));
// push_file_state(yylineno); // and filename ...
fprintf(yyout, "#line 0 \"%s\"\n", start);
}
<INITIAL,INDEF>^"#define"[ \t]+ { yy_push_state(DEF); }
/* <*>^"#line"[ \t]+(0-9)+[ \t]+["][^"]*["][ \t]*\n { } */
<DEF>[_A-Za-z][_:A-Za-z0-9]*/[^(] {
stb_define(yytext);
BEGIN DFV;
}
<DEF>{ID}/[(] { fprintf(stderr, "DEF::Found MACRO\n");
stb_define(yytext);
BEGIN DFA; }
<DFA>([^)]+) {
/* Process arguments */
stb_args(yytext);
BEGIN DFV;
}
<DFV>[ \t]+ { /* Ignore initial spaces */ }
<DFV>[.]*$ {/* Parse to end of line, get value for our define */
// printf("End of define, value = \'%s\'\n", yytext);
stb_macro(yytext);
yy_pop_state();
}
<INITIAL,INDEF>^[ \t]+.[dD][aA][tT][aA]? { fprintf(yyout, "\tWORD"); }
<INITIAL,INDEF>^"#defcont"[ \t]+ { yy_push_state(DFV); }
<INITIAL,INDEF>^"#ifdef"[ \t]* { ndef = 0; yy_push_state(IFDEFV); }
<INITIAL,INDEF>^"#ifndef"[ \t]* { ndef = 1; yy_push_state(IFDEFV); }
<IFDEFV>{ID} {
bool known = stb_isdefined(yytext);
if ( ((known)&&(ndef==0)) || ((!known)&&(ndef!=0)) ) {
BEGIN INDEF_EOL;
} else {
BEGIN INNOTDEF_EOL;
}
}
/* Not yet: <INITIAL,INDEF>^"#if"[ \t]* { yy_push_state(IFDEFE); }
/* Not yet: <INITIAL,INDEF>^"#if"[ \t]* { yy_push_state(IFDEFE); }
/* Not yet: <IFDEFE><expr> { yy_push_state(IFDEFE); } */
/* <INNOTDEF>^"#elsif"[ \t]* { yy_pop_state(); yy_push_state(IFDEFE); } */
<INDEF_EOL>[ \t]*$ { BEGIN INDEF; }
<INDEF_EOL>(;|"//").*$ { BEGIN INDEF; }
<INNOTDEF_EOL>[ \t]*$ { BEGIN INNOTDEF; }
<INNOTDEF_EOL>(;|"//").*$ { BEGIN INNOTDEF; }
<INDEF_EOL>[^ \t\n].*$ { BEGIN INDEF; fprintf(stderr, "WARNING! Unexpected characters on IFDEF line, \'%s\'\n", yytext); }
<INNOTDEF_EOL>[^ \t\n].*$ { BEGIN INNOTDEF; fprintf(stderr, "WARNING! Unexpected characters on IFNDEF line, %s\n", yytext); }
<INDEF,NVRDEF>^"#else"[ \t]*((;|"//").*)?$ { BEGIN NODEF; }
<INNOTDEF>^"#else"[ \t]*((;|"//").*)?$ { BEGIN INDEF; }
<INNOTDEF>(.*) { }
<INDEF>^"#elsif"[ \t]* { BEGIN NVRDEF; }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*((;|"//").*)?$ { yy_pop_state(); }
<NODEF,INDEF,INNOTDEF>^"#endif"[ \t]*"/*" { BEGIN COMMENT; }
<*>^"#endif"[ \t]* { fprintf(stderr, "ERR: Unknown endif!!\n");}
/* Not yet: ^"#struct"[ \t]* {} */
/* Not yet: ^"#endstruct"[ \t]* {} */
/* Not yet: ^"#seg"[ \t]* {} */
<NODEF,NVRDEF>.* { /* Ignore everything in these states*/ }
<INITIAL,INDEF>{ID}/[^(] {
if (stb_isdefined(yytext))
fprintf(yyout, "%s", stb_getdefn(yytext));
else
fprintf(yyout, "%s", yytext);
}
<*>^[ \t]*"//".*$ { /* Ignore comment only lines */ }
<*>^[ \t]*";".*$ { /* Ignore comment only lines */ }
<*>"//".* { /* Ignore trailing comments */ }
<*>";".* { /* Ignore trailing comments */ }
<*>"/*" { yy_push_state(COMMENT); }
<*>[ \t]+ { ECHO; }
<INITIAL,INDEF>[.]* { ECHO; }
<*>\n { ECHO; }
/* <*>. { printf("Unmatched \'%c\'\n", yytext[0]); } */
/* <<EOF>> { printf("EOF!\n"); } */
%%
class SYMTABLE_ENTRY {
private:
std::string &trim(std::string &s) {
std::string::iterator ptr = s.end();
while((ptr >= s.begin())&&(isspace(*ptr)))
*ptr-- = '\0';
return s;
}
public:
std::string m_name, m_value, m_args;
SYMTABLE_ENTRY(const char *str) : m_name(str) {
trim(m_name);
}
SYMTABLE_ENTRY &operator+=(const char *str) {
const char *start = str;
while(isspace(*start))
start++;
if (m_value.length()!=0)
m_value += " ";
std::string trimd(start);
trim(trimd);
m_value += trimd;
/*
printf("ENTRY::SYMBOL \'%s\' NOW = \'%s\'\n",
m_name.c_str(), m_value.c_str());
*/
return *this;
}
SYMTABLE_ENTRY &setargs(const char *str) {
m_args += str;
return *this;
}
std::string getdefn(void) {
return m_value;
}
};
class SYMBOL_TABLE {
private:
typedef SYMTABLE_ENTRY *TBLV;
typedef std::list<TBLV> TBLT;
TBLT m_tbl;
TBLT::iterator lookup(const char *str) {
TBLT::iterator i = m_tbl.begin();
for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
;
if ((i != m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())==0))
return i;
return m_tbl.end();
}
public:
SYMBOL_TABLE(void) {}
void define(const char *str) {
SYMTABLE_ENTRY *v = new SYMTABLE_ENTRY(str);
TBLT::iterator i = m_tbl.begin();
for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
;
m_tbl.insert(i, v);
// printf("SYMS::Defining SYMBOL: \'%s\'\n", str);
}
bool defined(const char *str) {
TBLT::iterator i = lookup(str);
if (i==m_tbl.end())
return false;
else
return true;
}
void undefine(const char *str) {
TBLT::iterator i = lookup(str);
if (i == m_tbl.end())
return;
TBLV v = (*i);
m_tbl.erase(i);
delete v;
}
void addmacro(const char *name, const char *str) {
TBLT::iterator i = lookup(name);
if (i == m_tbl.end()) {
fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
} *(*i) += str;
}
void addargs(const char *name, const char *str) {
TBLT::iterator i = lookup(name);
if (i == m_tbl.end()) {
fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
} (*i)->setargs(str);
}
const char *getdefn(const char *name) {
TBLT::iterator i = lookup(name);
if (i == m_tbl.end()) {
fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
return NULL;
} (*i)->getdefn().c_str();
}
};
SYMTABLE_ENTRY *last = NULL;
SYMBOL_TABLE syms;
std::string last_define;
void stb_define(const char *str) {
if (syms.defined(str)) {
fprintf(stderr, "WARNING! Symbol \'%s\' is already defined!\n", str);
syms.undefine(str);
}
syms.define(str);
last_define = str;
}
void stb_args(const char *args) {
syms.addargs(last_define.c_str(), args);
}
void stb_macro(const char *value) {
syms.addmacro(last_define.c_str(), value);
}
void stb_addmacro(const char *value) {
syms.addmacro(last_define.c_str(),value);
}
bool stb_isdefined(const char *str) {
return syms.defined(str);
}
const char *stb_getdefn(const char *str) {
return syms.getdefn(str);
}
int main(int argc, char **argv) {
yylex();
}
Go to most recent revision | Compare with Previous | Blame | View Log