mirror of
https://github.com/holub/mame
synced 2025-10-06 00:54:22 +03:00
Improved netlist parser
This commit is contained in:
parent
29213a99dc
commit
0adc956c61
@ -7,18 +7,24 @@
|
|||||||
|
|
||||||
#include "nl_parser.h"
|
#include "nl_parser.h"
|
||||||
|
|
||||||
|
#undef NL_VERBOSE_OUT
|
||||||
|
#define NL_VERBOSE_OUT(x) printf x
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// A netlist parser
|
// A netlist parser
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void netlist_parser::parse(char *buf)
|
void netlist_parser::parse(char *buf)
|
||||||
{
|
{
|
||||||
m_p = buf;
|
char c;
|
||||||
while (*m_p)
|
m_px = buf;
|
||||||
|
c = getc();
|
||||||
|
|
||||||
|
while (c)
|
||||||
{
|
{
|
||||||
pstring n;
|
pstring n;
|
||||||
skipws();
|
skipws();
|
||||||
if (!*m_p) break;
|
if (eof()) break;
|
||||||
n = getname('(');
|
n = getname('(');
|
||||||
NL_VERBOSE_OUT(("Parser: Device: %s\n", n.cstr()));
|
NL_VERBOSE_OUT(("Parser: Device: %s\n", n.cstr()));
|
||||||
if (n == "NET_ALIAS")
|
if (n == "NET_ALIAS")
|
||||||
@ -39,6 +45,7 @@ void netlist_parser::parse(char *buf)
|
|||||||
netdev_const(n);
|
netdev_const(n);
|
||||||
else
|
else
|
||||||
netdev_device(n);
|
netdev_device(n);
|
||||||
|
c = getc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,9 +100,9 @@ void netlist_parser::netdev_const(const pstring &dev_name)
|
|||||||
m_setup.register_dev(dev, name);
|
m_setup.register_dev(dev, name);
|
||||||
skipws();
|
skipws();
|
||||||
val = eval_param();
|
val = eval_param();
|
||||||
check_char(')');
|
|
||||||
paramfq = name + ".CONST";
|
paramfq = name + ".CONST";
|
||||||
NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val));
|
NL_VERBOSE_OUT(("Parser: Const: %s %f\n", name.cstr(), val));
|
||||||
|
check_char(')');
|
||||||
//m_setup.find_param(paramfq).initial(val);
|
//m_setup.find_param(paramfq).initial(val);
|
||||||
m_setup.register_param(paramfq, val);
|
m_setup.register_param(paramfq, val);
|
||||||
}
|
}
|
||||||
@ -110,12 +117,10 @@ void netlist_parser::netdev_device(const pstring &dev_type)
|
|||||||
devname = getname2(',', ')');
|
devname = getname2(',', ')');
|
||||||
dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
|
dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
|
||||||
m_setup.register_dev(dev, devname);
|
m_setup.register_dev(dev, devname);
|
||||||
skipws();
|
|
||||||
NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
|
NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
while (*m_p != ')')
|
while (getc() != ')')
|
||||||
{
|
{
|
||||||
m_p++;
|
|
||||||
skipws();
|
skipws();
|
||||||
pstring output_name = getname2(',', ')');
|
pstring output_name = getname2(',', ')');
|
||||||
pstring alias = pstring::sprintf("%s.[%d]", devname.cstr(), cnt);
|
pstring alias = pstring::sprintf("%s.[%d]", devname.cstr(), cnt);
|
||||||
@ -132,7 +137,6 @@ void netlist_parser::netdev_device(const pstring &dev_type)
|
|||||||
NL_VERBOSE_OUT(("variable inputs %s: %d\n", dev->name().cstr(), cnt));
|
NL_VERBOSE_OUT(("variable inputs %s: %d\n", dev->name().cstr(), cnt));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
check_char(')');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void netlist_parser::netdev_device(const pstring &dev_type, const pstring &default_param, bool isString)
|
void netlist_parser::netdev_device(const pstring &dev_type, const pstring &default_param, bool isString)
|
||||||
@ -144,17 +148,15 @@ void netlist_parser::netdev_device(const pstring &dev_type, const pstring &defau
|
|||||||
pstring defparam = devname + "." + default_param;
|
pstring defparam = devname + "." + default_param;
|
||||||
dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
|
dev = m_setup.factory().new_device_by_name(dev_type, m_setup);
|
||||||
m_setup.register_dev(dev, devname);
|
m_setup.register_dev(dev, devname);
|
||||||
skipws();
|
|
||||||
NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
|
NL_VERBOSE_OUT(("Parser: IC: %s\n", devname.cstr()));
|
||||||
if (*m_p != ')')
|
if (getc() != ')')
|
||||||
{
|
{
|
||||||
// have a default param
|
// have a default param
|
||||||
m_p++;
|
|
||||||
skipws();
|
skipws();
|
||||||
if (isString)
|
if (isString)
|
||||||
{
|
{
|
||||||
pstring val = getname(')');
|
pstring val = getname(')');
|
||||||
m_p--;
|
ungetc();
|
||||||
NL_VERBOSE_OUT(("Parser: Default param: %s %s\n", defparam.cstr(), val.cstr()));
|
NL_VERBOSE_OUT(("Parser: Default param: %s %s\n", defparam.cstr(), val.cstr()));
|
||||||
m_setup.register_param(defparam, val);
|
m_setup.register_param(defparam, val);
|
||||||
}
|
}
|
||||||
@ -174,46 +176,53 @@ void netlist_parser::netdev_device(const pstring &dev_type, const pstring &defau
|
|||||||
|
|
||||||
void netlist_parser::skipeol()
|
void netlist_parser::skipeol()
|
||||||
{
|
{
|
||||||
while (*m_p)
|
char c = getc();
|
||||||
|
while (c)
|
||||||
{
|
{
|
||||||
if (*m_p == 10)
|
if (c == 10)
|
||||||
{
|
{
|
||||||
m_p++;
|
c = getc();
|
||||||
if (*m_p && *m_p == 13)
|
if (c != 13)
|
||||||
m_p++;
|
ungetc();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_p++;
|
c = getc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void netlist_parser::skipws()
|
void netlist_parser::skipws()
|
||||||
{
|
{
|
||||||
while (*m_p)
|
while (unsigned char c = getc())
|
||||||
{
|
{
|
||||||
switch (*m_p)
|
switch (c)
|
||||||
{
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
case 13:
|
case 13:
|
||||||
m_p++;
|
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
if (*(m_p+1) == '/')
|
c = getc();
|
||||||
|
if (c == '/')
|
||||||
{
|
{
|
||||||
skipeol();
|
skipeol();
|
||||||
}
|
}
|
||||||
else if (*(m_p+1) == '*')
|
else if (c == '*')
|
||||||
{
|
{
|
||||||
m_p+=2;
|
int f=0;
|
||||||
while (*m_p && !(*m_p == '*' && *(m_p + 1) == '/' ))
|
while ((c = getc()) != 0 )
|
||||||
m_p++;
|
{
|
||||||
if (*m_p)
|
if (f == 0 && c == '*')
|
||||||
m_p += 2;
|
f=1;
|
||||||
|
else if (f == 1 && c== '/' )
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
f=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
ungetc();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,11 +232,11 @@ pstring netlist_parser::getname(char sep)
|
|||||||
{
|
{
|
||||||
char buf[300];
|
char buf[300];
|
||||||
char *p1 = buf;
|
char *p1 = buf;
|
||||||
|
char c;
|
||||||
|
|
||||||
while (*m_p != sep)
|
while ((c=getc()) != sep)
|
||||||
*p1++ = *m_p++;
|
*p1++ = c;
|
||||||
*p1 = 0;
|
*p1 = 0;
|
||||||
m_p++;
|
|
||||||
return pstring(buf);
|
return pstring(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,22 +244,27 @@ pstring netlist_parser::getname2(char sep1, char sep2)
|
|||||||
{
|
{
|
||||||
char buf[300];
|
char buf[300];
|
||||||
char *p1 = buf;
|
char *p1 = buf;
|
||||||
|
char c=getc();
|
||||||
|
|
||||||
while ((*m_p != sep1) && (*m_p != sep2))
|
while ((c != sep1) && (c != sep2))
|
||||||
*p1++ = *m_p++;
|
{
|
||||||
|
*p1++ = c;
|
||||||
|
c = getc();
|
||||||
|
}
|
||||||
*p1 = 0;
|
*p1 = 0;
|
||||||
|
ungetc();
|
||||||
return pstring(buf);
|
return pstring(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void netlist_parser::check_char(char ctocheck)
|
void netlist_parser::check_char(char ctocheck)
|
||||||
{
|
{
|
||||||
skipws();
|
skipws();
|
||||||
if (*m_p == ctocheck)
|
char c = getc();
|
||||||
|
if ( c == ctocheck)
|
||||||
{
|
{
|
||||||
m_p++;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_setup.netlist().xfatalerror("Parser: expected '%c' found '%c'\n", ctocheck, *m_p);
|
m_setup.netlist().xfatalerror("Parser: expected '%c' found '%c'\n", ctocheck, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
double netlist_parser::eval_param()
|
double netlist_parser::eval_param()
|
||||||
@ -261,16 +275,32 @@ double netlist_parser::eval_param()
|
|||||||
int f=0;
|
int f=0;
|
||||||
char *e;
|
char *e;
|
||||||
double ret;
|
double ret;
|
||||||
char *s = m_p;
|
|
||||||
|
|
||||||
|
pstring s = getname2(')',',');
|
||||||
|
|
||||||
|
printf("Got %s\n", s.cstr());
|
||||||
for (i=1; i<6;i++)
|
for (i=1; i<6;i++)
|
||||||
if (strncmp(s, macs[i], strlen(macs[i])) == 0)
|
if (strncmp(s.cstr(), macs[i], strlen(macs[i])) == 0)
|
||||||
f = i;
|
f = i;
|
||||||
ret = strtod(s+strlen(macs[f]), &e);
|
ret = strtod(s.substr(strlen(macs[f])).cstr(), &e);
|
||||||
if ((f>0) && (*e != ')'))
|
if ((f>0) && (*e != 0))
|
||||||
m_setup.netlist().xfatalerror("Parser: Error with parameter ...\n");
|
m_setup.netlist().xfatalerror("Parser: Error with parameter ...\n");
|
||||||
if (f>0)
|
if (f>0)
|
||||||
e++;
|
check_char(')');
|
||||||
m_p = e;
|
//if (f == 0)
|
||||||
|
// ungetc();
|
||||||
|
//if (f>0)
|
||||||
|
// e++;
|
||||||
|
//m_p = e;
|
||||||
return ret * facs[f];
|
return ret * facs[f];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char netlist_parser::getc()
|
||||||
|
{
|
||||||
|
return *(m_px++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void netlist_parser::ungetc()
|
||||||
|
{
|
||||||
|
m_px--;
|
||||||
|
}
|
||||||
|
@ -34,7 +34,11 @@ private:
|
|||||||
void check_char(char ctocheck);
|
void check_char(char ctocheck);
|
||||||
double eval_param();
|
double eval_param();
|
||||||
|
|
||||||
char * m_p;
|
unsigned char getc();
|
||||||
|
void ungetc();
|
||||||
|
bool eof() { return *m_px == 0; }
|
||||||
|
|
||||||
|
char * m_px;
|
||||||
netlist_setup_t &m_setup;
|
netlist_setup_t &m_setup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user