Subversion Repositories Vertical

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

%{
/*
 * $Id: acf_lex.l,v 1.2 2004/06/22 21:44:10 mjames Exp $ * 
 *
 * $Log: acf_lex.l,v $
 * Revision 1.2  2004/06/22 21:44:10  mjames
 * Firrst build most files
 *
 * Revision 1.30  2002/10/02 18:46:34  MJAMES
 * attribute is recognised in acfp syntax as well as vhdl
 *
 * Revision 1.29  2002/09/27 22:24:14  MJAMES
 * Separated out a quote as a token
 * Added VHDL_CONN token
 *
 * Revision 1.28  2002/09/16 11:03:50  mjames
 * Added some of the generic string  types  to the input parser.
 *
 * Revision 1.27  2002/09/09 10:14:58  mjames
 * Modified expression parser to match CC as previous one was
 * broken
 *
 * Revision 1.26  2002/08/23 14:21:55  mjames
 * Added the <VHDL> string keyword.
 *
 * Revision 1.25  2002/08/19 14:31:27  mjames
 * Removed an incompatibility with env_string generics where the output
 * of Vertical caused an error under some circumstances.
 *
 * Revision 1.24  2002/08/14 11:58:43  mjames
 * Corrected end-of-file behaviour that resulted in an infinite loop
 *
 * Revision 1.23  2002/08/06 12:56:21  mjames
 * Merge in from latest version
 *
 *
 * Revision 1.25  2002/08/06 09:25:23  mjames
 * Changed file include handler for an improved one.
 * Improvements created as a part of a microcode assembler
 *
 * Revision 1.24  2002/03/22 16:16:28  mjames
 * Modifications to undo over-zealous checking of
 * current chip even in incorrect scenarios.
 *
 * Revision 1.23  2002/03/21 17:11:32  mjames
 * Allowed '[' and ']' in acfp file syntax for pin identifiers in Quartus
 *
 * Revision 1.22  2002/01/21 09:28:49  mjames
 * coredump when opening non-existent Verilog include file due to
 * use of NULL file pointer. Avoided by not using file pointer until certain
 * that file was opened properly.
 *
 * Revision 1.21  2002/01/16 10:04:35  mjames
 * Added package definitions to VHDL syntax
 * According to report by John Marquis
 *
 * Revision 1.20  2001/12/13 22:12:16  mjames
 * Vertical now supports nested include database files
 * This allows wrappers around 'pure' VHDL or Verilog files
 *
 * Revision 1.19  2001/12/11 21:29:56  mjames
 * Verilog syntax now read in by Vertical allows pin templates
 * defined  by Certify to be used.
 *
 * Revision 1.18  2001/11/30 22:21:19  mjames
 * Modifying Verilog reading syntax to accept valid code.
 *
 * Revision 1.17  2001/11/19 10:41:54  mjames
 * Merged back DTC release
 *
 * Revision 1.16.2.1  2001/11/16 15:10:59  mjames
 * Removed an unecessary local variable
 *
 * Revision 1.16  2001/10/31 22:19:56  mjames
 * Tidying up problematical comments caused by CVS
 * 'intelligent' comment guessing
 *
 * Revision 1.15  2001/09/28 14:34:13  mjames
 * FIxed yydebug variable to exist when YYDEBUG macro
 * is not defined. Otherwise linker error will be reported.
 *
 * Revision 1.14  2001/09/16 20:01:06  mjames
 * tidying
 *
 * Revision 1.13  2001/07/09 09:36:30  mjames
 * Amending the syntax and end of file behaviour to allow Quartus pin fit files
 * to be read .
 * They are harder to read because they are not block structured. The end of file is used as a marker. Vertical has been persuaded to handle end of file events properly.
 *
 * Revision 1.12  2001/07/06 12:50:36  mjames
 * Added the ability to read in Quartus pinfit files
 *
 * Revision 1.11  2001/07/05 15:12:36  MJAMES
 * Amended to read Quartus pin files. not fully working
 *
 * Revision 1.10  2001/06/06 12:10:27  mjames
 * Move from HPUX
 *
 * Revision 1.9  2001/04/30 10:01:08  Administrator
 * Have finally got the Verilog/VHDL comment pragma parser working.
 *
 * Revision 1.8  2001/04/30 07:55:53  mjames
 * Improving parsing of Verilog, still a few loose ends
 *
 * Revision 1.7  2001/04/27 22:30:10  mjames
 * Starting to get comment and pragma handling OK.
 * Added correct header file includes to lx_support.c
 *
 * Revision 1.6  2001/03/29 08:27:06  mjames
 * Converted frbread for use with the newer files from the drawing office
 *
 * Revision 1.5  2001/02/21 16:37:33  mjames
 * Provided a new method of defining port maps with VHDL which allows for short
 * cut definitions.
 *
 * Cleaned up TCL/Tk interfacing issues
 *
 * Revision 1.4  2001/01/02 07:53:51  mjames
 * Made changes to allow for interface with TCL/Tk
 *
 * Revision 1.3  2000/12/04 12:55:48  mjames
 * Copied files back from HPUX to create definitive CygWin version
 *
 * Then amended the syntax of ACFP files so that a/2 was no longer
 * seen as "a/2" but instead as "a" divided_by 2. This was a throwback
 * to some of the earlier efforts at variant syntax for VHDL and ACFP
 * parsing.
 *
 * Revision 1.2  2000/10/19 22:19:49  mjames
 * removed header lines
 *
 * Revision 1.1.1.1  2000/10/19 21:58:34  mjames
 * Mike put it here
 *
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

/* see makefile for how this appears */

#include "vertcl_main.h"
#include "expression.h"
#include "generic.h"
#include "database.h"
#include "acf_yacc.h"
#include "lx_support.h"
#include "cmdparse.h"
#include "cmdlog.h"
#include "cmdutil.h"
#include "yywrap.h"




#define YYLMAX MAXIDLEN

#if !defined YY_START
#define YY_START (yybgin -1 -yysvec)
#endif

/* YY_INPUT redefinition
   keep the original definition, replace with a function which will
   check a flag and either use the original file reading version or read from
   a string */











#define MAX_INCLUDE_DEPTH 10




#ident "@(#)$Header: C:/cvsroot/Vert03/acf_src/acf_lex.l,v 1.2 2004/06/22 21:44:10 mjames Exp $"

/* state stores for include files */
YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
struct str * incl_first = NULL, * incl_last = NULL;
char * filename[MAX_INCLUDE_DEPTH];
int    old_linenumber[MAX_INCLUDE_DEPTH];
FILE * handles[MAX_INCLUDE_DEPTH];


int include_stack_ptr = 0;


char lex_from_string = 0;

extern int errorseen;
extern  int yyval;
extern int yydebug;
extern int lineno;


extern int inside_block; /* flag to help 'generic' context dependence */

generic_info_t info;

int prev_begin = -1;
int prev_begin_include = -1;
int read_state = 1; /* start off by reading */

int comment_type = 0;

void lex_exec_line(void);

void skip_to_eol(void);
void skip_c_comment(void);
void exit_lex_block(void);


int  my_yyinput(char * buf , int max_size);


static char * yyerr_start_names[] = {
 "INITIAL",
 "vhdl",
 "Verilog",
 "ACFplus",
 "skipping",
 "C (Verilog) comment",
 "VHDL comment",
 "Command line expression",
 "Include file area"
 };

/* token forced into LEX by method described in
   Lex & Yacc , O'Reilly page 206 */ 
  int start_grammar;


%}


/* removed '.' '-' ':' '/' ',' from here as it is now a unique token */
/* Permit '$' as this could become a variable to be expanded in make_string */
L   [A-Za-z0-9_\~\$]
L2  [A-Za-z0-9_\~\|\$]
/* do not permit square brackets in ACFP syntax inside strings (to be handled properly) */
L2A  [A-Za-z0-9_\~\|/\$]
L2D [A-Za-z0-9_\\$\.]
/* no / in this set, as its a valid arithmetic operator */
L2V [A-Za-z0-9_\~\|\$]

S [^\"]
Q [\"]


Ct [ -\~]

Cm [^\n]



D [0-9]
Spc [ \t]

/* lex directive */
%p 4000
%a 2500
%e 1500
%k 2000
%n 1000

/* can have VHDL Verilog and ACFP keywords defined exclusively */
/* s inclusive set */
%x vhdl
%x vlog
%x acfp
%x pragma
%x vert_c_comment
%x vert_vhdl_comment
/* expression tokens are used on the command line */
%x expr
/* copied almost verbatim from the examples given */
%x incl



%%
%{

/* Page 206, Lex & Yacc , O'Reilly */
/* solution to multiple lexers */

  if(start_grammar)    
    {
    int tmp = start_grammar;
    start_grammar = 0;
    return tmp;
    }
%}


<INITIAL,acfp,vhdl>include            { prev_begin_include = YY_START;  BEGIN(incl); }

<vlog>'include                        { prev_begin_include = YY_START;  BEGIN(incl); }


 <incl>[ \t]*      /* eat the whitespace */
 <incl>[^ \t\n]+   { /* got the include file name */
         if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
             {
             Log(LOG_ERROR, "-- Includes nested too deeply\n" );
             exit( 1 );
             }
         if(errorseen)
             {
             Log(LOG_ERROR, "-- skipping include: previous error\n" );
             exit( 1 );
             }
       
/*         printf("++ Using Begin=%s\n",yyerr_start_names[YY_START]); */


         include_stack[include_stack_ptr] =
             YY_CURRENT_BUFFER;
         /* expand arguments in string */
         
         old_linenumber[include_stack_ptr]= lineno;

         handles[include_stack_ptr] = yyin;

         include_stack_ptr++;
         

         filename[include_stack_ptr] = strdup(yytext);

         yyin = fopen( filename[include_stack_ptr], "r" );

         if ( ! yyin )
             {
             Log(LOG_ERROR, "-- cannot open include file '%s'\n",filename[include_stack_ptr]);
             include_stack_ptr -= 1;
             lineno = old_linenumber[include_stack_ptr];
/*             yy_switch_to_buffer(
                  include_stack[include_stack_ptr] );
*/
             yyin = handles[include_stack_ptr];

             }
         else
           {
         lineno = 1;
           
           yy_switch_to_buffer(
             
             yy_create_buffer( yyin, YY_BUF_SIZE ) );
           }
         BEGIN(prev_begin_include);
         }

<<EOF>> {
/*         rewind(yyin); */
/*           printf("-- +++ At level %d\n",include_stack_ptr); */
         if ( include_stack_ptr ==  0 )
             {
/*             printf("lex: termination\n");   */
/*              YY_FLUSH_BUFFER;
             yy_delete_buffer( YY_CURRENT_BUFFER );
*/
              exit_lex_block();
              yyterminate();
             }

         else
             {
/*             printf("lex: backup level in file buffer\n"); */
/*              YY_FLUSH_BUFFER; */
             include_stack_ptr --;
             yy_delete_buffer( YY_CURRENT_BUFFER );
             lineno = old_linenumber[include_stack_ptr];
             yyin = handles[include_stack_ptr];
             yy_switch_to_buffer(
                  include_stack[include_stack_ptr] );
             }
/*         printf("handle ending"); */
         break;
         }



<INITIAL,acfp,vlog,vhdl>"\""         { char t;
                    char * p;
                    char buff[MAXIDLEN];

                    int c;   /* quoted string using either type of quotes,
                              * including  escaped quotes */
       
                    t  = *yytext; /* determine terminator */

                    p =  buff; /* setup destination */

                    for(;;) { 
                       
                      c = input();
                      if (c == t)
                        break;
                        
                      if(c=='\n') { 
                        lineno++;
                        Log(LOG_GENERAL,"Carriage Return in string (line %d)\n",lineno);
                        continue;
                        }
                      
                      if (c=='\\') {
                         *p++ = c;
                         c = input();
                         }
                      if(c==EOF) {
                        Log(LOG_GENERAL,"End of file in string\n");
                        break;
                        }
                      if(c<' ') {
                        Log(LOG_GENERAL,"Ctl char 0x%02X in string\n",c);
                        break; 
                        }
                       
                        *p++ = c;
                      if((p - buff) >= MAXIDLEN-100) {
                        Log(LOG_GENERAL,"No closing quote after %d chars in string\n",MAXIDLEN-100);
                        break;
                        }

                    }
                    *p = 0;   
                    yylval.string = make_string(buff,&lx_first,&lx_last) ;
/*                    printf("quoted (yytext:'%s')\n",yylval.string); */
                    if(yydebug) fprintf(stderr,"String (quo) ='%s'\n",yylval.string); 
                    return(QUOTED_STRING); 
 }; 

<vlog>"\\"  { char * p;
              char buff[MAXIDLEN];

              int c;
              p =  buff; /* setup destination */
              while(1) { 
                c = input();
                if (!isalnum(c) && c!='[' && c!=']') /* any non-space char */
                  break;
                *p++ = c;
                }

             *p = 0;   
             yylval.string = make_string(buff,&lx_first,&lx_last) ;
             if(yydebug) fprintf(stderr,"String (escaped) ='%s'\n",yylval.string); 
             return(QUOTED_STRING); 
             }; 






<INITIAL,acfp,vhdl,pragma>"--" { 
/*
                                printf("-- vhdl comment"); 
*/
                            one_line_comment:
                                if(YY_START!=pragma)
                                  prev_begin=YY_START; 
                                comment_type= vert_vhdl_comment;
                                BEGIN(vert_vhdl_comment); 
                                break; };
<INITIAL,vlog>"//" { 
/*
                                printf("-- vhdl comment"); 
*/
                                goto one_line_comment;
                                 };


<INITIAL,acfp,vlog,pragma>"/*" {
/*
                                printf("-- C comment");  
*/
                                if(YY_START!=pragma)
                                  prev_begin=YY_START; 
                                comment_type= vert_c_comment;
                                BEGIN(vert_c_comment); 
                                break; 
};

                                
<acfp>[rR][eE][aA][dD]_[oO][fF][fF] { 
/*
                              printf(" Read Off");
*/
                              if (comment_type == vert_c_comment) 
                                skip_c_comment();
                              if (comment_type == vert_vhdl_comment) 
                                skip_to_eol();
/*
                              printf(" Skipped comment\n");
*/
                              read_state = 0;
                              BEGIN(pragma);
                              break;
                              };

<acfp>[rR][eE][aA][dD]_[oO][nN] { 
/*
                              printf(" Read On");
*/
                              if (comment_type == vert_c_comment) 
                                skip_c_comment();
                              if (comment_type == vert_vhdl_comment) 
                                skip_to_eol(); 
/*
                              printf(" Skipped comment\n");
*/
                              read_state = 1;
                              if(prev_begin>= 0) 
                                 BEGIN(prev_begin);
                              break;
                              };
                              
                           
<pragma,vert_vhdl_comment,vert_c_comment>[Vv][Ee][Rr][Tt][Ii][Cc][Aa][Ll]{Spc}* {
/*
                              printf(" Vertical");
*/
                             /* the line is acfp syntax */ 
                BEGIN (acfp);  break; };



<vert_vhdl_comment,acfp>"\n" {
             lineno++;
             if (comment_type == vert_vhdl_comment )
               {
/*
               printf(" endline\n");
*/
               comment_type = -1; 
               lineno++;
               if(read_state==0) /* parser was not reading, so go back into pragma context */
                 BEGIN(pragma);
               else             /* parser was reading, so go back into pre-comment context */
                 BEGIN(prev_begin);
                break;
               }
             }; 

<vert_c_comment,acfp,vlog,INITIAL>"*/" {
               /* pickup only inside a pragma enclosed in a C comment */ 
/*
               printf(" end C comment\n");
*/
               if (comment_type != vert_c_comment )
                 Log(LOG_ERROR,"-- close comment unexpected\n");
               comment_type = -1;
               if(read_state==0) /* parser was not reading, so go back into pragma context */
                 BEGIN(pragma);
               else             /* parser was reading, so go back into pre-comment context */
                 BEGIN(prev_begin);
                break;
               }; 




<vert_c_comment>"\n"                { lineno++; break; };

<pragma>"\n"                          { lineno++; break; };
<vert_c_comment,pragma>"\r"              { break; };

<vert_vhdl_comment,vert_c_comment>{Spc} { break; }; 

<vert_vhdl_comment>. {skip_to_eol();
                      goto ignored_comment;
                      };

<vert_c_comment>.   { skip_c_comment();
                 ignored_comment:
                      comment_type = -1; 
                      if(read_state==0) /* parser was not reading, so go back into pragma context */
                        BEGIN(pragma);
                      else             /* parser was reading, so go back into pre-comment context */
                        BEGIN(prev_begin);
                       break; };
<pragma>. { break; };


<INITIAL,vlog,expr,vhdl>"\'"                  { return QUOTE;   };
<INITIAL,acfp,vhdl>"=>"                       { return CONNECTED; };
<INITIAL,acfp,vlog,vhdl,expr>":="             { return ASSIGN; };
<INITIAL,acfp,vhdl>"<="                       { return SIG_ASSIGN; };
<INITIAL,acfp,vlog,vhdl,expr>":"              { return (':'); };
<INITIAL,acfp,vlog,vhdl,expr>";"              { return (';');  };
<INITIAL,acfp,vlog,expr>"="                   { return ('='); };
<INITIAL,acfp,vlog,vhdl,expr>"("              { return ('(');  };
<INITIAL,acfp,vlog,vhdl,expr>")"              { return (')');  };
<INITIAL,acfp,vlog,vhdl>"."                   { return ('.');  }; 
<INITIAL,acfp,vlog,vhdl>"!"                   { return ('!');  }; 
<INITIAL,acfp,vlog,vhdl,expr>"+"              { return ('+');  };
<INITIAL,acfp,vlog,vhdl,expr>"-"              { return ('-');  };
<vhdl>"/="                                    { return (N_EQ); };
<INITIAL,acfp,vlog,vhdl,expr>"/"              { return ('/');  };
<INITIAL,acfp,vlog,expr>"%"                   { return ('%');  };
<INITIAL,acfp,vlog,expr>"?"                   { return ('?');  };
<INITIAL,acfp,vlog,expr>"<<"                  { return (SHL); };
<INITIAL,acfp,vlog,expr>">>"                  { return (SHR); };
<INITIAL,acfp,vlog,expr>"<"                   { return ('<'); };
<INITIAL,acfp,vlog,expr>">"                   { return ('>'); };
<INITIAL,acfp,vlog,expr>"^"                   { return ('^'); };
<INITIAL,acfp,vlog,expr>"~"                   { return ('~'); };
<INITIAL,acfp,vlog,expr>"&&"                  { return (LOG_AND); };
<INITIAL,acfp,vlog,expr>"&"                   { return ('&'); };
<INITIAL,acfp,vlog,expr>"||"                  { return (LOG_OR); };
<INITIAL,acfp,vlog,expr>"|"                   { return ('|'); };


<INITIAL,acfp,vlog,expr>"=="                  { return (EQ_EQ); };
<vhdl>"="                                     { return (EQ_EQ); };
<INITIAL,acfp,vlog,expr>"!="                  { return (N_EQ); };
<INITIAL,acfp,vhdl,expr>"**"                  { return (TO_POW);  };
<INITIAL,acfp,vlog,vhdl,expr>"*"              { return ('*');  };
<INITIAL,acfp,vlog,vhdl>","                   { return (',');  };
<vlog,acfp>"["                                { return ('['); };
<vlog,acfp>"]"                                { return (']'); };


<INITIAL,acfp,vlog,vhdl,expr>{Spc}    { break; };

<INITIAL,acfp,vlog,vhdl>"\n"              { lineno++; if(yydebug) printf("line %d\n",lineno); break; };
<INITIAL,acfp,vlog,vhdl>"\r"              { break; };



            
<acfp>[eE][xX][eE][cC]                   {  lex_exec_line();goto ignored_comment; /* commands to vertical */ };


<INITIAL>[aA][hH][dD][lL]                                   { BEGIN(acfp);prev_begin=acfp;
                                                                             Log(LOG_GENERAL,"Entering ACFP block\n");
                                                                             inside_block=1;
                                                                             return (AHDL); }  
<INITIAL>[cC][hH][iI][pP]                                   { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (CHIP);  }
<INITIAL>[jJ][oO][iI][nN][eE][dD]_[nN][eE][tT][sS]          { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (JOINED_NETS); } ;
<INITIAL>[cC][oO][mM][pP][oO][nN][eE][nN][tT][sS]           { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (COMPONENTS); };
<INITIAL>[rR][eE][nN][aA][mM][eE]_[pP][iI][nN][sS]          { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (RENAME_PINS); } ;
<INITIAL>[tT][eE][mM][pP][lL][aA][tT][eE]                   { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (TEMPLATE); } ;
<INITIAL,acfp,vlog,vhdl>[vV][hH][dD][lL]                                   { BEGIN(vhdl);
                                                                             Log(LOG_GENERAL,"Entering VHDL block\n");
                                                                             inside_block=1;
                                                                             prev_begin=vhdl;
                                                                             return (VHDL); } ;

<INITIAL,acfp,vlog,vhdl>[vV][eE][rR][iI][lL][oO][gG]                      { BEGIN(vlog);
                                                                             Log(LOG_GENERAL,"Entering Verilog block\n");
                                                                             prev_begin=vlog;
                                                                             inside_block=1;
                                                                             return (VERILOG); } ;

<INITIAL,acfp,vlog,vhdl>[wW][iI][rR][eE][dD]_[nN][eE][tT][sS]              { BEGIN(acfp);prev_begin=acfp;
                                                                             inside_block=1;
                                                                             return (WIRED_NETS); };
<INITIAL,acfp,vlog,vhdl>[gG][eE][nN][eE][rR][iI][cC]                       { if (!inside_block) /* special */
                                                                             { inside_block=1;
                                                                               BEGIN(vhdl);prev_begin=vhdl; };
                                                                             return (GENERIC);};
<vhdl>[aA][lL][lL]                                           { return (ALL); } 
<vhdl>[aA][rR][cC][hH][iI][tT][eE][cC][tT][uU][rR][eE]       { return (ARCHITECTURE); } 
<acfp,vhdl>[aA][tT][tT][rR][iI][bB][uU][tT][eE]              { return (ATTRIBUTE); } 
<acfp>[aA][sS][sS][iI][gG][nN][eE][dD]                       { return (ASSIGNED); } 
<acfp,vhdl>[aA][lL][iI][aA][sS]                              { return (ALIAS); } 
<acfp>[aA][nN]                                               { return (AN); } 
<acfp,vlog,vhdl>[bB][eE][gG][iI][nN]                         { return (BEGIN_TOK); } 
<acfp>[bB][iI][dD][iI][rR]_[pP][iI][nN]                      { yylval.integer = BIDIR;  return(PINDIR); }
<acfp>[bB][iI][dD][iI][rR]                                   { yylval.integer = BIDIR;  return(PINDIR); }
<vhdl>[bB][oO][oO][lL][eE][aA][nN]                           { return(BOOLEAN); }
<vhdl>[iI][nN][oO][uU][tT]                                   { yylval.integer = BIDIR;  return(PINDIR); }
<vlog>[oO][uU][tT]                                           { yylval.integer = BIDIR;  return(PINDIR); }
<acfp>[bB][uU][fF][fF][eE][rR]_[pP][iI][nN]                  { yylval.integer = BUFFER; return(PINDIR);  }
<vhdl>[bB][uU][fF][fF][eE][rR]                               { yylval.integer = BUFFER; return(PINDIR);  }
<acfp>[cC][oO][nN][fF][iI][gG]_[pP][iI][nN]                  { yylval.integer = CONFIG; return(PINDIR); };
<vhdl>[cC][oO][mM][pP][oO][nN][eE][nN][tT]                   { return (COMPONENT); };
<vhdl>[cC][oO][nN][sS][tT][aA][nN][tT]                       { return (CONSTANT); };
<acfp>[cC][oO][nN][nN][eE][cC][tT][iI][oO][nN]               { return (CONN); };
<acfp>[vV][hH][dD][lL]_[cC][oO][nN][nN]                       { return (VHDL_CONN); };
<acfp>[dD][eE][cC][lL][aA][rR][aA][tT][iI][oO][nN]           { return (DECLARATION); };
<acfp>[dD][eE][vV][iI][cC][eE]                               { return (DEVICE); };
<vhdl,acfp,expr>[dD][oO][wW][nN][tT][oO]                          { return (DOWNTO);  };
<acfp,vlog,vhdl>[eE][nN][dD]                                 { return (END); /* do not free_strings here as it is too early !! */};
<acfp>[eE][nN][dD]_[cC][oO][nN][nN]                          { return (END_CONN); } ;
<vlog>endmodule                                              { return (ENDMODULE); };
<acfp,vhdl>[eE][nN][tT][iI][tT][yY]                          { return (ENTITY); };
<acfp>[eE][qQ][uU][iI][vV][aA][lL][eE][nN][tT]               { return (EQUIVALENT); };
<vhdl>[eE][nN][vV]_[sS][tT][rR][iI][nN][gG]                  { return (ENV_STRING); };
<vhdl,expr>[fF][aA][lL][sS][eE]                                   { return (FALSE); };
<acfp>[fF][iI][xX]_[lL][oO][cC][aA][tT][iI][oO][nN]          { return (FIX_LOCATION); }; 
<vhdl>[fF][oO][rR]                                           { return (FOR); };
<acfp>[gG][nN][dD]\*                                         { return (GND_RES_IO); };
<acfp>[gG][nN][dD]\+                                         { return (GND_RES_IN); };
<acfp>[gG][nN][dD]{L2}*                                      { yylval.string = make_string(yytext,&lx_first,&lx_last);
                                                               if(yydebug) fprintf(stderr,"String (GND) ='%s'\n",yytext); 
                                                               return (GND); };
<acfp>[iI][nN][pP][uU][tT]_[pP][iI][nN]                      { yylval.integer = INPUT;  return(PINDIR); };
<vhdl>[iI][nN]                                               { yylval.integer = INPUT;  return(PINDIR); };
<vlog,acfp>[iI][nN][pP][uU][tT]                                   { yylval.integer = INPUT;  return(PINDIR); };
<vlog>[iI][nN][oO][uU][tT]                                   { yylval.integer = BIDIR;  return(PINDIR); }
<acfp>[iI][nN][sS][tT][aA][nN][cC][eE]                       { return (INSTANCE); };
<acfp,vhdl>[iI][nN][tT][eE][gG][eE][rR]                      { return (INTEGER); };
<acfp,vhdl>[iI][sS]                                          { return (IS);  };
<acfp>[jJ][uU][mM][pP][eE][rR]                               { return (JUMPER); } ;
<vhdl>[lL][iI][bB][rR][aA][rR][yY]                           { return (LIBRARY); } ;
<acfp>[lL][oO][cC][aA][tT][iI][oO][nN]                       { return (LOCATION); } ;
<vhdl>[mM][aA][pP]                                           { return (MAP); };
<vlog>module                                                 { return (MODULE); };
<acfp>[nN][oO][nN][eE]                                       { yylval.integer = NONE;   return(PINDIR); };
<acfp>[nN][aA][mM][eE][dD]                                   { return (NAMED); } ;
<vhdl>[oO][fF]                                               { return (OF); };
<acfp>[oO][uU][tT][pP][uU][tT]_[pP][iI][nN]                  { yylval.integer = OUTPUT; return(PINDIR); };
<vlog,acfp>[oO][uU][tT][pP][uU][tT]                               { yylval.integer = OUTPUT; return(PINDIR); };
<vhdl>[oO][uU][tT]                                           { yylval.integer = OUTPUT; return(PINDIR); };
<vhdl>[oO][pP][eE][nN]                                       { return (OPEN); };
<vhdl>[pP][aA][cC][kK][aA][gG][eE]                           { return (PACKAGE); }; 
<vhdl>[pP][oO][rR][tT]                                       { return (PORT); };
<acfp>[pP][oO][wW][eE][rR]_[pP][iI][nN]                      { yylval.integer = POWER; return(PINDIR); };
<acfp,vlog,vhdl>[rR][aA][nN][gG][eE]                         { return (RANGE); };
<acfp>[rR][oO][uU][tT][eE]_[fF][lL][aA][gG][sS]              { return (ROUTE_FLAGS); };
<acfp>[rR][oO][uU][tT][eE][dD]                               { return (ROUTED); } ;
<vhdl>[sS][hH][lL]                                           { return (SHL); };
<vhdl>[sS][hH][rR]                                           { return (SHR); };
<vhdl>[sS][iI][gG][nN][aA][lL]                               { return (ASIGNAL); };
<vhdl>[sS][tT][rR][iI][nN][gG]                               { return (STRING); };
<vlog>[sS][uU][bB][dD][eE][sS][iI][gG][nN]                   { return (SUBDESIGN); };
<acfp,vhdl,expr>[tT][oO]                                          { return (TO);  };
<vhdl,expr>[tT][rR][uU][eE]                                       { return (TRUE); };
<acfp>[uU][nN][rR][oO][uU][tT][eE][dD]                       { return (UNROUTED); } ;
<acfp>[vV][cC][cC]{L2}*                                      { yylval.string = make_string(yytext,&lx_first,&lx_last);
                                                               if(yydebug) fprintf(stderr,"String (VCC) ='%s'\n",yytext); 
                                                               return (VCC);  };
<vhdl>[uU][sS][eE]                                           { return (USE);  };
<vlog>wire                                                   { return (WIRE); };       

<INITIAL,acfp,expr>{D}{L2D}*   { yylval.string = make_string(yytext,&lx_first,&lx_last); /* do it anyway */
                           if(yydebug) fprintf(stderr,"String (num) ='%s'\n",yytext); 
                           return(NUM_STRING); };

<vlog,vhdl,expr>{D}{L2V}*     { yylval.string = make_string(yytext,&lx_first,&lx_last); /* do it anyway */
                     if(yydebug) fprintf(stderr,"String (num) ='%s'\n",yytext); 
                      return(NUM_STRING); };

<INITIAL,acfp,expr>{L}{L2A}*     { yylval.string = make_string(yytext,&lx_first,&lx_last); /* do it anyway */
                     if(yydebug) fprintf(stderr,"String (num) ='%s'\n",yytext); 
                      return(TXT_STRING); };

<vlog,vhdl,expr>{L}{L2V}*            {  yylval.string = make_string(yytext,&lx_first,&lx_last); /* do it anyway */
                     if(yydebug) fprintf(stderr,"String (txt) ='%s'\n",yytext); 
                      return(isdigit(yylval.string[0])?NUM_STRING : TXT_STRING); };

<vlog>"/"{L2D}+   { yylval.string = make_string(yytext,&lx_first,&lx_last); /* do it anyway */
                     if(yydebug) fprintf(stderr,"String (num) ='%s'\n",yytext); 
                      return(TXT_STRING); };


<INITIAL,acfp,vlog,vhdl>.                { printf("-- error in %s syntax: found character code 0x%02X (%c) at line %d\n",yyerr_start_names[YY_START],yytext[0],yytext[0]>32?yytext[0]:'.',lineno); break; };


%%


/* terminate an ACFP and VHDL comment */
void skip_to_eol(void) {
  int c;
  for(;;) {
    c=input();
    if (c=='\n' || c==EOF) {
      lineno++;
      return;
      }
    }/* VHDL comment */ 
  }
   

   

/* execute a command line command  */
  char stringbuff[MAXIDLEN];
void lex_exec_line(void) {
  int c,i;
  for(i=0;i<MAXIDLEN-2;) {
    c=input();
    stringbuff[i++] = c;
    if (c=='\n' || c==EOF) {
      lineno++;
      stringbuff[i]=0;
      ExecuteString (stringbuff ,yy_nArgs, yy_Args);
      return;
      }
    }
   stringbuff[i] = 0;
   ExecuteString (stringbuff ,yy_nArgs,yy_Args);
  }




/* supporting functions need to be in sane file so LEX macros work */
void skip_c_comment(void) {
  int c;
  for(;;) { 
    while(((c = input()) !=EOF) && (c != '*')) {
      if(c=='\n') 
        lineno++;
      }
    if (c=='*') {
      while((c = input()) == '*')    putchar(c); 
      if(c=='\n') 
        lineno++;
      if (c=='/')
        break;
      }
    if(c==EOF) {
      Log(LOG_GENERAL,"End of file in comment\n");
      break;
      }
    }
  }

void exit_lex_block(void) {
  inside_block = 0;
  prev_begin=INITIAL;
  BEGIN(INITIAL);
  }

void tidy_lex(void) 
  {
  errorseen = 0;
  include_stack_ptr = 0;
  exit_lex_block();
  start_grammar = FILEMODE;
  }




int yyerror(char * x)
  {

  if (!errorseen) {
    if(include_stack_ptr==0)
      { 
      Log(LOG_ERROR,"--  Error in %s syntax\n--  -->%s near string (%s) at line %d\n",
              yyerr_start_names[YY_START],x,yytext,lineno);
      }
    else
      {
      Log(LOG_ERROR,"--  File %s: Error in %s syntax\n--  -->%s near string (%s) at line %d\n",
             filename[include_stack_ptr],yyerr_start_names[YY_START],x,yytext,lineno);
      }
    }
  errorseen = 1;
  include_stack_ptr = 0;
  exit_lex_block();
  YY_FLUSH_BUFFER;
  yyterminate();
  return 1;
  }



/********************************************************/
/* Reading generic expressions from a string            */
/********************************************************/

static char * myinputptr;
static char * myinputlim;
/* this is exported */
expression_t * cmd_expression;


int my_yyinput(char * buf, int max_size)
  {
  int n;
  n =(max_size < (myinputlim-myinputptr))? max_size :myinputlim-myinputptr;
  if(n>0)
    {
    memcpy(buf,myinputptr,n);
    myinputptr+=n;
    }
  return n;
  }


/* this function requires a large number of declarations from 
  lex. */
  


expression_t * compile_expression_from_string(char * s)
  {
  int prev_expr_begin;
  myinputptr = s;
  myinputlim = s+strlen(s);
  prev_expr_begin = YY_START;

  BEGIN(expr);
  
  start_grammar = CMDMODE;
  lex_from_string = 1;  
  
  yy_scan_buffer  (s, strlen(s)); // new code no macro mangle 
 
    
  lex_from_string = 0;
  BEGIN(prev_expr_begin);

  return cmd_expression;
  }