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:
Stefan Frederik 2020-11-30 01:36:28 +01:00
parent eda64b7ee1
commit 5533ca87a4
3 changed files with 144 additions and 96 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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[]);