updated parselabel.l to allow more generic node names and/or spaces: these are now valid "a a,bb[3 : 0] , ccc", "1,2,3" and various other improvemenst and "ugly" code removals
This commit is contained in:
parent
eda64b7ee1
commit
5533ca87a4
231
src/parselabel.l
231
src/parselabel.l
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
#define CAD_SPICE_NETLIST 1
|
#define CAD_SPICE_NETLIST 1
|
||||||
|
|
||||||
int dbg_var = 0;
|
int dbg_var = 3;
|
||||||
extern int netlist_type;
|
extern int netlist_type;
|
||||||
extern int has_x;
|
extern int has_x;
|
||||||
extern FILE *errfp;
|
extern FILE *errfp;
|
||||||
|
|
@ -57,9 +57,9 @@ typedef struct /* used in expandlabel.y */
|
||||||
|
|
||||||
Stringptr dest_string={NULL,0}; /*19102004; */
|
Stringptr dest_string={NULL,0}; /*19102004; */
|
||||||
|
|
||||||
static int bracket=0;
|
|
||||||
extern int yyparse(void) ;
|
extern int yyparse(void) ;
|
||||||
extern int yyparse_error;
|
extern int yyparse_error;
|
||||||
|
extern int yylex();
|
||||||
|
|
||||||
void clear_expandlabel_data(void)
|
void clear_expandlabel_data(void)
|
||||||
{
|
{
|
||||||
|
|
@ -79,6 +79,16 @@ void strreplace(char s[], char chr, char repl_chr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void parse(const char *s)
|
||||||
|
{
|
||||||
|
YY_BUFFER_STATE buf;
|
||||||
|
buf=yy_scan_string(s);
|
||||||
|
while(yylex()){
|
||||||
|
fprintf(errfp, "token:|%s|\n", yytext);
|
||||||
|
}
|
||||||
|
yy_delete_buffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
const char *expandlabel(const char *s, int *m)
|
const char *expandlabel(const char *s, int *m)
|
||||||
{
|
{
|
||||||
YY_BUFFER_STATE buf;
|
YY_BUFFER_STATE buf;
|
||||||
|
|
@ -86,7 +96,6 @@ const char *expandlabel(const char *s, int *m)
|
||||||
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "expandlabel(): entering\n");
|
if(dbg_var >= 3) fprintf(errfp, "expandlabel(): entering\n");
|
||||||
buf=yy_scan_string(s);
|
buf=yy_scan_string(s);
|
||||||
bracket=0;
|
|
||||||
yyparse();
|
yyparse();
|
||||||
yy_delete_buffer(buf);
|
yy_delete_buffer(buf);
|
||||||
if(yyparse_error==1) {
|
if(yyparse_error==1) {
|
||||||
|
|
@ -125,131 +134,161 @@ const char *expandlabel(const char *s, int *m)
|
||||||
Lexical analyzer
|
Lexical analyzer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%x net_label
|
%x index
|
||||||
%x next_to_alias
|
%x mult
|
||||||
%x rest
|
|
||||||
|
|
||||||
|
SP [ \t]*
|
||||||
ID [-#+_\\/=a-zA-Z0-9]*[-#@+_\\/=a-zA-Z]+[-#@+_\\/=a-zA-Z0-9]*
|
INT [0-9]+
|
||||||
ID_NUM [-#+_\\/=a-zA-Z0-9]+
|
DDOT {SP}".."{SP}
|
||||||
|
CLN {SP}":"{SP}
|
||||||
ID_EXT ([-~#+/=_a-zA-Z][-~#@\\/ :.=_+a-zA-Z0-9]*)|([-~#+/.=_a-zA-Z][-~#@\\/ :=_+a-zA-Z0-9]*)
|
LAB [-a-zA-Z_%$~#/\\<>]
|
||||||
ID_EXT_PARENTHESIS [-~#+/=_a-zA-Z][-#@\\/:.=_+a-zA-Z0-9]*\([-#@\\/:.=_+a-zA-Z0-9]*\)
|
/* includes numbers */
|
||||||
|
LAB_NUM [-a-zA-Z_%$~#/\\<>0-9]
|
||||||
|
/* includes numbers and space and *+(). */
|
||||||
|
IDX_LAB_NUM_SP [-a-zA-Z_%$~#/\\<> \t0-9*+().]
|
||||||
|
/* identifier, may start with a number */
|
||||||
|
IDX_ID_NUM ({LAB_NUM}+({IDX_LAB_NUM_SP}*{LAB_NUM})*)
|
||||||
|
/* identifier, not starting with a number */
|
||||||
|
IDX_ID (("("|{LAB})+{IDX_LAB_NUM_SP}*)
|
||||||
|
/* includes numbers and space and +(). */
|
||||||
|
LAB_NUM_SP [-a-zA-Z_%$~#/\\<> \t0-9+().]
|
||||||
|
/* identifier, may start with a number */
|
||||||
|
ID_NUM ({LAB_NUM}+({LAB_NUM_SP}*{LAB_NUM})*)
|
||||||
|
/* identifier, not starting with a number */
|
||||||
|
ID (("("|{LAB})+{LAB_NUM_SP}*)
|
||||||
|
/* ~#diUV=9_(\#-hgvUY=) */
|
||||||
|
ID_EXT_PARENTHESIS ([-~#+/=_a-zA-Z][-#@\\/:.=_+a-zA-Z0-9]*\([-#@\\/:.=_+a-zA-Z0-9]*\))
|
||||||
|
|
||||||
%%
|
%%
|
||||||
^(alias|ipin|iopin|opin)[+ \n]+[^+\n ]+/[\n +]+ {
|
/* this action resets initial condition at start of line. This is extremely useful if previously lexer
|
||||||
yylval.ptr.str=NULL; /*19102004 */
|
* bailed out in the middle of some non INITIAL start condition due to yyparse() syntax errors */
|
||||||
/* these things are freed after use in expandlabel.y */
|
<mult,index>^. {
|
||||||
my_strdup(298, &yylval.ptr.str, yytext);
|
|
||||||
BEGIN(next_to_alias);
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): alias, yytext = %s\n", yytext);
|
|
||||||
return B_LINE;
|
|
||||||
}
|
|
||||||
<next_to_alias>[\n +]+ { /* get all white space and return a single separator */
|
|
||||||
BEGIN(net_label);
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): next_to_alias, yytext = %s\n", yytext);
|
|
||||||
yylval.val=yytext[0];
|
|
||||||
return B_CAR;
|
|
||||||
}
|
|
||||||
^[^*] {
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): matched: ^[^*] |%s|, push back\n",yytext);
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): matched: ^[^*] |%s|, push back\n",yytext);
|
||||||
yyless(0); /* push entire token back to input */
|
yyless(0); /* push entire token back to input */
|
||||||
BEGIN(net_label); /* we know that a label follows. */
|
BEGIN(INITIAL); /* reset parser */
|
||||||
/* so go and process it. */
|
}
|
||||||
}
|
|
||||||
^\*.* { /* a comment, return as LINE token */
|
|
||||||
yylval.ptr.str=NULL; /*19102004 */
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_LINE: %s\n",yytext);
|
|
||||||
my_strdup(299, &yylval.ptr.str, yytext); /* freed after use in expandlabel.y */
|
|
||||||
return B_LINE;
|
|
||||||
}
|
|
||||||
<net_label>{
|
|
||||||
|
|
||||||
[ \n]+ { /* this ends the <net_label> start condition */
|
<mult>{
|
||||||
BEGIN(rest);
|
/* postfix multiplier */
|
||||||
yylval.val=yytext[0];
|
{INT} {
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_CAR: %s\n",yytext);
|
sscanf(yytext, "%d",&yylval.val);
|
||||||
return B_CAR;
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): postmult B_NUM: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return B_NUM;
|
||||||
}
|
}
|
||||||
\.\. {
|
} /* end <mult> */
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_DOUBLEDOT: %s\n", yytext);
|
|
||||||
|
/* node indexes: "3:2" "5:1:2" "5..1" "7..1..2" "b:a" "c:b:a" .... */
|
||||||
|
<index>{
|
||||||
|
{INT} {
|
||||||
|
sscanf(yytext, "%d",&yylval.val);
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_IDXNUM: |%s|\n", yytext);
|
||||||
|
return B_IDXNUM;
|
||||||
|
}
|
||||||
|
{SP}\.\.{SP} {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_DOUBLEDOT: |%s|\n", yytext);
|
||||||
return B_DOUBLEDOT;
|
return B_DOUBLEDOT;
|
||||||
}
|
}
|
||||||
[0-9]+{ID_EXT} {
|
/* end vector node index "...]" */
|
||||||
yylval.ptr.str=NULL;
|
\] {
|
||||||
my_strdup(452, &yylval.ptr.str, yytext);
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): close bracket: %s\n", yytext);
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME 3: %s\n", yytext);
|
BEGIN(INITIAL);
|
||||||
return B_NAME;
|
return yytext[0];
|
||||||
|
}
|
||||||
|
[^ ] {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): idx character: |%s|\n", yytext);
|
||||||
|
return yytext[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recognize AA[aa:bb:33] or AA[33:cc:dd] or AA[aa..bb..11] .... */
|
/* recognize AA[aa:bb:33] or AA[33:cc:dd] or AA[aa..bb..11] .... */
|
||||||
({ID}\.\.{ID_NUM}\.\.{ID_NUM})|({ID_NUM}\.\.{ID}\.\.{ID_NUM})|({ID_NUM}\.\.{ID_NUM}\.\.{ID}) {
|
({IDX_ID}{DDOT}{IDX_ID_NUM}{DDOT}{IDX_ID_NUM})|({IDX_ID_NUM}{DDOT}{IDX_ID}{DDOT}{IDX_ID_NUM})|({IDX_ID_NUM}{DDOT}{IDX_ID_NUM}{DDOT}{IDX_ID}) {
|
||||||
yylval.ptr.str=NULL;
|
yylval.ptr.str=NULL;
|
||||||
my_strdup(428, &yylval.ptr.str, yytext);
|
my_strdup(428, &yylval.ptr.str, yytext);
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME 2: %s\n", yytext);
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME3: |%s|\n", yytext);
|
||||||
return B_NAME;
|
return B_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
({ID}:{ID_NUM}:{ID_NUM})|({ID_NUM}:{ID}:{ID_NUM})|({ID_NUM}:{ID_NUM}:{ID}) {
|
({IDX_ID}{CLN}{IDX_ID_NUM}{CLN}{IDX_ID_NUM})|({IDX_ID_NUM}{CLN}{IDX_ID}{CLN}{IDX_ID_NUM})|({IDX_ID_NUM}{CLN}{IDX_ID_NUM}{CLN}{IDX_ID}) {
|
||||||
yylval.ptr.str=NULL;
|
yylval.ptr.str=NULL;
|
||||||
my_strdup(430, &yylval.ptr.str, yytext);
|
my_strdup(430, &yylval.ptr.str, yytext);
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME 2: %s\n", yytext);
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME2: |%s|\n", yytext);
|
||||||
return B_NAME;
|
return B_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* recognize AA[width-1:0], AA[0:width-1], AA[width-1..4], AA[3..width+3], AA[aa:bb] AA[aa..bb] */
|
/* recognize AA[width-1:0], AA[0:width-1], AA[width-1..4], AA[3..width+3], AA[aa:bb] AA[aa..bb] */
|
||||||
({ID}:{ID_NUM})|({ID_NUM}:{ID})|({ID}\.\.{ID_NUM})|({ID_NUM}\.\.{ID}) {
|
({IDX_ID}{CLN}{IDX_ID_NUM})|({IDX_ID_NUM}{CLN}{IDX_ID})|({IDX_ID}{DDOT}{IDX_ID_NUM})|({IDX_ID_NUM}{DDOT}{IDX_ID}) {
|
||||||
yylval.ptr.str=NULL;
|
yylval.ptr.str=NULL;
|
||||||
my_strdup(92, &yylval.ptr.str, yytext);
|
my_strdup(92, &yylval.ptr.str, yytext);
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME 1: %s\n", yytext);
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME1: |%s|\n", yytext);
|
||||||
return B_NAME;
|
return B_NAME;
|
||||||
}
|
}
|
||||||
|
} /* end <index> */
|
||||||
|
|
||||||
[0-9]+ {
|
/* a comment, return as LINE token */
|
||||||
sscanf(yytext, "%d",&yylval.val);
|
^\*.* {
|
||||||
if(bracket) {
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_IDXNUM: %s\n", yytext);
|
|
||||||
return B_IDXNUM;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NUM: %s\n", yytext);
|
|
||||||
return B_NUM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* recognize the most esotheric identifiers */
|
|
||||||
{ID_EXT}|{ID_EXT_PARENTHESIS} {
|
|
||||||
yylval.ptr.str=NULL;/*19102004 */
|
|
||||||
my_strdup(300, &yylval.ptr.str, yytext); /* freed after use in expandlabel.y */
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME: %s\n", yytext);
|
|
||||||
return B_NAME;
|
|
||||||
}
|
|
||||||
\[ {
|
|
||||||
bracket++;
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): open bracket: %s\n", yytext);
|
|
||||||
return yytext[0];
|
|
||||||
}
|
|
||||||
\] {
|
|
||||||
bracket--;
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): close bracket: %s\n", yytext);
|
|
||||||
return yytext[0];
|
|
||||||
}
|
|
||||||
[^ ] {
|
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): returning character: %s\n", yytext);
|
|
||||||
return yytext[0];
|
|
||||||
}
|
|
||||||
} /* end <net_label> */
|
|
||||||
|
|
||||||
<rest>{ /* treat rest of line as a single LINE token */
|
|
||||||
(.|\n)* {
|
|
||||||
yylval.ptr.str=NULL; /*19102004 */
|
yylval.ptr.str=NULL; /*19102004 */
|
||||||
my_strdup(301, &yylval.ptr.str, yytext); /* freed after use in expandlabel.y */
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_LINE: |%s|\n",yytext);
|
||||||
if(dbg_var >= 3) fprintf(errfp, "yylex(): <rest> B_LINE: %s\n",yytext);
|
my_strdup(299, &yylval.ptr.str, yytext); /* freed after use in expandlabel.y */
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
return B_LINE;
|
return B_LINE;
|
||||||
}
|
}
|
||||||
|
/* prefix multiplier */
|
||||||
|
{INT}/{SP}\*{SP} {
|
||||||
|
sscanf(yytext, "%d",&yylval.val);
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): premult B_NUM: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return B_NUM;
|
||||||
|
}
|
||||||
|
/* a number: if not a multiplier nor a node index return as a node name */
|
||||||
|
{INT} {
|
||||||
|
yylval.ptr.str=NULL;
|
||||||
|
my_strdup(120, &yylval.ptr.str, yytext);
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME4: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return B_NAME;
|
||||||
|
}
|
||||||
|
{SP} {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): skipping: |%s|\n", yytext);
|
||||||
|
}
|
||||||
|
/* comma separator between nodes: chop spaces "a,b , c" */
|
||||||
|
{SP},{SP} {
|
||||||
|
yylval.val=',';
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): comma: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return ',';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recognize the most esotheric identifiers */
|
||||||
|
{ID_NUM}|{ID_EXT_PARENTHESIS} {
|
||||||
|
yylval.ptr.str=NULL;/*19102004 */
|
||||||
|
my_strdup(300, &yylval.ptr.str, yytext); /* freed after use in expandlabel.y */
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): B_NAME0: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return B_NAME;
|
||||||
|
}
|
||||||
|
/* start vector node index: "aa[" */
|
||||||
|
\[ {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): open bracket: %s\n", yytext);
|
||||||
|
BEGIN(index);
|
||||||
|
return yytext[0];
|
||||||
|
}
|
||||||
|
/* "*(aa,bb,cc)" or "*aaa" prefix multiplication*/
|
||||||
|
{SP}\*{SP}/({ID}|[(]) {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): pre *: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
/* "*16" postfix multiplication */
|
||||||
|
{SP}\*{SP}/{INT} {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): post *: |%s|\n", yytext);
|
||||||
|
BEGIN(mult);
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
[^ ] {
|
||||||
|
if(dbg_var >= 3) fprintf(errfp, "yylex(): character: |%s|\n", yytext);
|
||||||
|
BEGIN(INITIAL);
|
||||||
|
return yytext[0];
|
||||||
|
}
|
||||||
|
|
||||||
} /* end rest */
|
|
||||||
<*><<EOF>> {
|
<*><<EOF>> {
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@
|
||||||
|
|
||||||
#include "xschem.h"
|
#include "xschem.h"
|
||||||
|
|
||||||
|
extern char yytext[];
|
||||||
|
extern int yylex (void);
|
||||||
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||||
|
YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
|
||||||
|
|
||||||
void statusmsg(char str[],int n)
|
void statusmsg(char str[],int n)
|
||||||
{
|
{
|
||||||
static char s[2048];
|
static char s[2048];
|
||||||
|
|
@ -1740,6 +1745,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(argc == 3 && !strcmp(argv[1],"parselabel")) {
|
||||||
|
parse( argv[2]);
|
||||||
|
}
|
||||||
else if(argc == 3 && !strcmp(argv[1],"expandlabel")) {
|
else if(argc == 3 && !strcmp(argv[1],"expandlabel")) {
|
||||||
int tmp, llen;
|
int tmp, llen;
|
||||||
char *result=NULL;
|
char *result=NULL;
|
||||||
|
|
|
||||||
|
|
@ -1016,6 +1016,7 @@ extern void check_arc_storage(int c);
|
||||||
extern void check_line_storage(int c);
|
extern void check_line_storage(int c);
|
||||||
extern void check_polygon_storage(int c);
|
extern void check_polygon_storage(int c);
|
||||||
extern const char *expandlabel(const char *s, int *m);
|
extern const char *expandlabel(const char *s, int *m);
|
||||||
|
extern void parse(const char *s);
|
||||||
extern void clear_expandlabel_data(void);
|
extern void clear_expandlabel_data(void);
|
||||||
extern void merge_inst(int k, FILE *fd);
|
extern void merge_inst(int k, FILE *fd);
|
||||||
extern void merge_file(int selection_load, const char ext[]);
|
extern void merge_file(int selection_load, const char ext[]);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue