Modified Files:
Makefile.am
Added Files:
cmpp/Makefile cmpp/cmpp.h cmpp/ifs_lex.l cmpp/ifs_yacc.h
cmpp/ifs_yacc.y cmpp/main.c cmpp/mod_lex.l cmpp/mod_yacc.h
cmpp/mod_yacc.y cmpp/pp_ifs.c cmpp/pp_lst.c cmpp/pp_mod.c
cmpp/read_ifs.c cmpp/util.c cmpp/writ_ifs.c
Version of cmpp from xspice, still needs some work to make it compatable
with SpiceOpus and tclspice, but compiles.
This commit is contained in:
parent
fcae1791c5
commit
ad5e06720a
|
|
@ -9,7 +9,7 @@ EXTRA_DIST = README
|
|||
## libs. It is currently compiled manually, last.
|
||||
##SUBDIRS = mif cm enh evt ipc idn icm
|
||||
|
||||
SUBDIRS = mif cm enh evt ipc idn
|
||||
SUBDIRS = mif cm enh evt ipc idn cmpp
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/include -I$(top_srcdir)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
cmpp_OBJS=main.o pp_ifs.o pp_lst.o pp_mod.o read_ifs.o util.o writ_ifs.o \
|
||||
ifs_yacc.o ifs_lex.o mod_yacc.o mod_lex.o
|
||||
|
||||
cmpp_GEN=ifs_yacc.c ifs_tok.h \
|
||||
ifs_lex.c ifs_lex.h \
|
||||
mod_lex.c mod_lex.h \
|
||||
mod_yacc.c mod_tok.h
|
||||
|
||||
YACC=bison -d --yacc
|
||||
#YACC=yacc -d
|
||||
|
||||
CC=gcc -O2 -g
|
||||
|
||||
LEX=flex -t
|
||||
|
||||
all: cmpp
|
||||
|
||||
cmpp: $(cmpp_OBJS)
|
||||
$(CC) -o cmpp $(cmpp_OBJS)
|
||||
|
||||
%.c : %.y
|
||||
$(YACC) -p $(*:yacc=)yy $<
|
||||
mv -f y.tab.c $*.c
|
||||
mv -f y.tab.h $(*:yacc=)tok.h
|
||||
|
||||
%.c : %.l
|
||||
$(LEX) -P$(*:lex=)yy $< > $@
|
||||
|
||||
ifs_lex.c : ifs_lex.l
|
||||
$(LEX) -i -P$(*:lex=)yy $< > $@
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(cmpp_OBJS) $(cmpp_GEN) cmpp
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
/*============================================================================
|
||||
FILE cmpp.h
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains shared constants, type definitions,
|
||||
and function prototypes used in the cmpp process.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define IFSPEC_FILENAME "ifspec.ifs"
|
||||
#define UDNFUNC_FILENAME "udnfunc.c"
|
||||
#define MODPATH_FILENAME "modpath.lst"
|
||||
#define UDNPATH_FILENAME "udnpath.lst"
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
typedef enum {
|
||||
|
||||
OK, /* Returned with no error */
|
||||
ERROR, /* Returned with error */
|
||||
|
||||
} Status_t;
|
||||
|
||||
|
||||
|
||||
#define GET_IFS_TABLE 0 /* Read the entire ifs table */
|
||||
#define GET_IFS_NAME 1 /* Get the C function name out of the table only */
|
||||
|
||||
#define MAX_PATH_LEN 1024 /* Maximum pathname length */
|
||||
#define MAX_NAME_LEN 1024 /* Maximum SPICE name length */
|
||||
#define MAX_FN_LEN 31 /* Maximum filename length */
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
/* Structures used by parser to check for valid connections/parameters */
|
||||
/* ******************************************************************** */
|
||||
|
||||
/*
|
||||
* The boolean type
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
FALSE,
|
||||
TRUE,
|
||||
} Boolean_t;
|
||||
|
||||
|
||||
/*
|
||||
* The direction of a connector
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
IN,
|
||||
OUT,
|
||||
INOUT,
|
||||
} Dir_t;
|
||||
|
||||
|
||||
/*
|
||||
* The type of a port
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
VOLTAGE, /* v - Single-ended voltage */
|
||||
DIFF_VOLTAGE, /* vd - Differential voltage */
|
||||
CURRENT, /* i - Single-ended current */
|
||||
DIFF_CURRENT, /* id - Differential current */
|
||||
VSOURCE_CURRENT, /* vnam - Vsource name for input current */
|
||||
CONDUCTANCE, /* g - Single-ended VCIS */
|
||||
DIFF_CONDUCTANCE, /* gd - Differential VCIS */
|
||||
RESISTANCE, /* h - Single-ended ICVS */
|
||||
DIFF_RESISTANCE, /* hd - Differential ICVS */
|
||||
DIGITAL, /* d - Digital */
|
||||
USER_DEFINED, /* <identifier> - Any user defined type */
|
||||
} Port_Type_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The type of a parameter or Static_Var
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
BOOLEAN,
|
||||
INTEGER,
|
||||
REAL,
|
||||
COMPLEX,
|
||||
STRING,
|
||||
POINTER, /* NOTE: POINTER should not be used for Parameters - only
|
||||
* Static_Vars - this is enforced by the cmpp.
|
||||
*/
|
||||
} Data_Type_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The complex type
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
double real;
|
||||
double imag;
|
||||
} Complex_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Values of different types.
|
||||
*
|
||||
* Note that a struct is used instead of a union for conformity
|
||||
* with the use of the Mif_Value_t type in the simulator where
|
||||
* the type must be statically initialized. ANSI C does not
|
||||
* support useful initialization of unions.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
||||
Boolean_t bvalue; /* For BOOLEAN parameters */
|
||||
int ivalue; /* For INTEGER parameters */
|
||||
double rvalue; /* For REAL parameters */
|
||||
Complex_t cvalue; /* For COMPLEX parameters */
|
||||
char *svalue; /* For STRING parameters */
|
||||
|
||||
} Value_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Information about the model as a whole
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
char *c_fcn_name; /* Name used in the C function */
|
||||
char *model_name; /* Name used in a spice deck */
|
||||
char *description; /* Description of the model */
|
||||
|
||||
} Name_Info_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Information about a connection
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
char *name; /* Name of this connection */
|
||||
char *description; /* Description of this connection */
|
||||
Dir_t direction; /* IN, OUT, or INOUT */
|
||||
Port_Type_t default_port_type; /* The default port type */
|
||||
char *default_type; /* The default type in string form */
|
||||
int num_allowed_types; /* The size of the allowed type arrays */
|
||||
Port_Type_t *allowed_port_type; /* Array of allowed types */
|
||||
char **allowed_type; /* Array of allowed types in string form */
|
||||
Boolean_t is_array; /* True if connection is an array */
|
||||
Boolean_t has_conn_ref; /* True if there is associated with an array conn */
|
||||
int conn_ref; /* Subscript of the associated array conn */
|
||||
Boolean_t has_lower_bound; /* True if there is an array size lower bound */
|
||||
int lower_bound; /* Array size lower bound */
|
||||
Boolean_t has_upper_bound; /* True if there is an array size upper bound */
|
||||
int upper_bound; /* Array size upper bound */
|
||||
Boolean_t null_allowed; /* True if null is allowed for this connection */
|
||||
|
||||
} Conn_Info_t;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Information about a parameter
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
||||
char *name; /* Name of this parameter */
|
||||
char *description; /* Description of this parameter */
|
||||
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
||||
Boolean_t has_default; /* True if there is a default value */
|
||||
Value_t default_value; /* The default value */
|
||||
Boolean_t has_lower_limit; /* True if there is a lower limit */
|
||||
Value_t lower_limit; /* The lower limit for this parameter */
|
||||
Boolean_t has_upper_limit; /* True if there is a upper limit */
|
||||
Value_t upper_limit; /* The upper limit for this parameter */
|
||||
Boolean_t is_array; /* True if parameter is an array */
|
||||
Boolean_t has_conn_ref; /* True if there is associated with an array conn */
|
||||
int conn_ref; /* Subscript of the associated array conn */
|
||||
Boolean_t has_lower_bound; /* True if there is an array size lower bound */
|
||||
int lower_bound; /* Array size lower bound */
|
||||
Boolean_t has_upper_bound; /* True if there is an array size upper bound */
|
||||
int upper_bound; /* Array size upper bound */
|
||||
Boolean_t null_allowed; /* True if null is allowed for this parameter */
|
||||
|
||||
} Param_Info_t;
|
||||
|
||||
|
||||
/*
|
||||
* Information about an instance variable
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
||||
char *name; /* Name of this parameter */
|
||||
char *description; /* Description of this parameter */
|
||||
Data_Type_t type; /* Data type, e.g. REAL, INTEGER, ... */
|
||||
Boolean_t is_array; /* True if parameter is an array */
|
||||
|
||||
} Inst_Var_Info_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The all encompassing structure for the ifs table information
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
||||
Name_Info_t name; /* The name table entries */
|
||||
int num_conn; /* Number of entries in the connection table(s) */
|
||||
Conn_Info_t *conn; /* Array of connection info structs */
|
||||
int num_param; /* Number of entries in the parameter table(s) */
|
||||
Param_Info_t *param; /* Array of parameter info structs */
|
||||
int num_inst_var; /* Number of entries in the instance var table(s) */
|
||||
Inst_Var_Info_t *inst_var; /* Array of instance variable info structs */
|
||||
|
||||
} Ifs_Table_t;
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
|
||||
void preprocess_ifs_file(void);
|
||||
|
||||
void preprocess_lst_files(void);
|
||||
|
||||
void preprocess_mod_file(char *filename);
|
||||
|
||||
|
||||
void print_error(char *message);
|
||||
|
||||
|
||||
Status_t read_ifs_file(char *filename, int mode, Ifs_Table_t *ifs_table);
|
||||
|
||||
Status_t write_ifs_c_file(char *filename, Ifs_Table_t *ifs_table);
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
%option yylineno
|
||||
%option noyywrap
|
||||
%{ /* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE ifs_lex.l
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
12/31/91 Bill Kuhn Change "array" to "vector" and "array_bounds"
|
||||
to "vector_bounds".
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file defines tokens applicable to parsing the ifspec.ifs
|
||||
file, and actions to be taken on encountering those tokens.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
ifs_yacc.y
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "ifs_yacc.h"
|
||||
#include "ifs_tok.h"
|
||||
|
||||
int yyival;
|
||||
double yydval;
|
||||
extern int atoi();
|
||||
extern double atof();
|
||||
|
||||
/*
|
||||
* IFS specs are case insensitive:
|
||||
*/
|
||||
|
||||
/* saj - use -i flex command line option
|
||||
#undef input
|
||||
#define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:isupper(yytchar)?tolower(yytchar):yytchar)
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
%}
|
||||
|
||||
%start BOOL CTYPE DIR DTYPE
|
||||
|
||||
%x comment stringl
|
||||
|
||||
%p 5000
|
||||
|
||||
W [ \t\n]
|
||||
A [_a-z]
|
||||
D [0-9]
|
||||
I [a-z_]
|
||||
Z [0-9a-z_]
|
||||
E [eE][+-]?{D}+
|
||||
|
||||
%%
|
||||
|
||||
"/*" { BEGIN(comment); }
|
||||
|
||||
<comment>[^*\n]* /* eat anything that's not a '*' */
|
||||
|
||||
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
|
||||
|
||||
<comment>\n /* new line */
|
||||
|
||||
<comment><<EOF>> {ifs_yyerror ("Unterminated comment"); yyterminate(); }
|
||||
|
||||
<comment>"*"+"/" { BEGIN(INITIAL); }
|
||||
|
||||
"\"" { BEGIN(stringl); }
|
||||
|
||||
<stringl>[^\"]* { return TOK_STRING_LITERAL; }
|
||||
|
||||
<stringl>"\"" { BEGIN(INITIAL); }
|
||||
|
||||
<stringl><<EOF>> {ifs_yyerror ("Unterminated string literal");
|
||||
yyterminate(); }
|
||||
|
||||
allowed_types{W}*: {BEGIN CTYPE; return TOK_ALLOWED_TYPES;}
|
||||
vector{W}*: {BEGIN BOOL; return TOK_ARRAY;}
|
||||
vector_bounds{W}*: {return TOK_ARRAY_BOUNDS;}
|
||||
c_function_name{W}*: {return TOK_C_FUNCTION_NAME;}
|
||||
port_name{W}*: {return TOK_PORT_NAME;}
|
||||
port_table{W}*: {return TOK_PORT_TABLE;}
|
||||
data_type{W}*: {BEGIN DTYPE; return TOK_DATA_TYPE;}
|
||||
default_type{W}*: {BEGIN CTYPE; return TOK_DEFAULT_TYPE;}
|
||||
default_value{W}*: {return TOK_DEFAULT_VALUE;}
|
||||
description{W}*: {return TOK_DESCRIPTION;}
|
||||
direction{W}*: {BEGIN DIR; return TOK_DIRECTION;}
|
||||
static_var_name{W}*: {return TOK_STATIC_VAR_NAME;}
|
||||
static_var_table{W}*: {return TOK_STATIC_VAR_TABLE;}
|
||||
limits{W}*: {return TOK_LIMITS;}
|
||||
name_table{W}*: {return TOK_NAME_TABLE;}
|
||||
null_allowed{W}*: {BEGIN BOOL; return TOK_NULL_ALLOWED;}
|
||||
parameter_name{W}*: {return TOK_PARAMETER_NAME;}
|
||||
parameter_table{W}*: {return TOK_PARAMETER_TABLE;}
|
||||
spice_model_name{W}*: {return TOK_SPICE_MODEL_NAME;}
|
||||
|
||||
<BOOL>yes {return TOK_BOOL_YES;}
|
||||
<BOOL>no {return TOK_BOOL_NO;}
|
||||
true {return TOK_BOOL_YES;}
|
||||
false {return TOK_BOOL_NO;}
|
||||
|
||||
<CTYPE>v {return TOK_CTYPE_V;}
|
||||
<CTYPE>vd {return TOK_CTYPE_VD;}
|
||||
<CTYPE>vnam {return TOK_CTYPE_VNAM;}
|
||||
<CTYPE>i {return TOK_CTYPE_I;}
|
||||
<CTYPE>id {return TOK_CTYPE_ID;}
|
||||
<CTYPE>g {return TOK_CTYPE_G;}
|
||||
<CTYPE>gd {return TOK_CTYPE_GD;}
|
||||
<CTYPE>h {return TOK_CTYPE_H;}
|
||||
<CTYPE>hd {return TOK_CTYPE_HD;}
|
||||
<CTYPE>d {return TOK_CTYPE_D;}
|
||||
|
||||
<DIR>in {return TOK_DIR_IN;}
|
||||
<DIR>out {return TOK_DIR_OUT;}
|
||||
<DIR>inout {return TOK_DIR_INOUT;}
|
||||
|
||||
<DTYPE>real {return TOK_DTYPE_REAL;}
|
||||
<DTYPE>int {return TOK_DTYPE_INT;}
|
||||
<DTYPE>boolean {return TOK_DTYPE_BOOLEAN;}
|
||||
<DTYPE>complex {return TOK_DTYPE_COMPLEX;}
|
||||
<DTYPE>string {return TOK_DTYPE_STRING;}
|
||||
<DTYPE>pointer {return TOK_DTYPE_POINTER;}
|
||||
|
||||
"<" {return TOK_LANGLE;}
|
||||
">" {return TOK_RANGLE;}
|
||||
"[" {return TOK_LBRACKET;}
|
||||
"]" {return TOK_RBRACKET;}
|
||||
"," {return TOK_COMMA;}
|
||||
"-" {return TOK_DASH;}
|
||||
|
||||
|
||||
{I}+{Z}* {return TOK_IDENTIFIER;}
|
||||
|
||||
[+-]?{D}+ {yyival = atoi (yytext);
|
||||
return TOK_INT_LITERAL;}
|
||||
|
||||
[+-]?{D}+"."{D}*({E})? |
|
||||
[+-]?{D}*"."{D}+({E})? |
|
||||
[+-]?{D}+({E})? {yydval = atof (yytext);
|
||||
return TOK_REAL_LITERAL;}
|
||||
|
||||
. ; /* ignore anything else */
|
||||
\n ; /* ignore anything else */
|
||||
|
||||
%%
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void reset_lex_context ()
|
||||
{
|
||||
BEGIN 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE ifs_yacc.h
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
Typedefs needed by the YYSTYPE union (%union operator) in the yacc
|
||||
file. These are only used in the yacc file, but must be defined here since
|
||||
the generated token.h file includes a definition of the union YYSTYPE.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "cmpp.h"
|
||||
|
||||
typedef struct {
|
||||
Boolean_t has_value;
|
||||
Data_Type_t kind;
|
||||
union {
|
||||
Boolean_t bvalue;
|
||||
int ivalue;
|
||||
double rvalue;
|
||||
Complex_t cvalue;
|
||||
char *svalue;
|
||||
} u;
|
||||
} My_Value_t;
|
||||
|
||||
typedef struct {
|
||||
Boolean_t has_bound;
|
||||
My_Value_t bound;
|
||||
} Bound_t;
|
||||
|
||||
typedef struct {
|
||||
Boolean_t is_named;
|
||||
union {
|
||||
char *name;
|
||||
struct {
|
||||
Bound_t upper;
|
||||
Bound_t lower;
|
||||
} bounds;
|
||||
} u;
|
||||
} Range_t;
|
||||
|
||||
typedef struct {
|
||||
Port_Type_t kind;
|
||||
char *id; /* undefined unless kind == USER_DEFINED */
|
||||
} My_Port_Type_t;
|
||||
|
||||
typedef struct ctype_list_s {
|
||||
My_Port_Type_t ctype;
|
||||
struct ctype_list_s *next;
|
||||
} Ctype_List_t;
|
||||
|
|
@ -0,0 +1,901 @@
|
|||
%{ /* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE ifs_yacc.y
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
12/31/91 Bill Kuhn Fix bug in usage of strcmp in check_default_type()
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the BNF specification of the language used in
|
||||
the ifspec.ifs file together with various support functions,
|
||||
and parses the ifspec.ifs file to get the information from it
|
||||
and place this information into a data structure
|
||||
of type Ifs_Table_t.
|
||||
|
||||
INTERFACES
|
||||
|
||||
yyparse() - Generated automatically by UNIX 'yacc' utility.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
ifs_lex.l
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "ifs_yacc.h"
|
||||
|
||||
extern int yylineno;
|
||||
extern int yyival;
|
||||
extern double yydval;
|
||||
extern char *ifs_yytext;
|
||||
extern char *strdup();
|
||||
|
||||
Boolean_t parser_just_names;
|
||||
static Boolean_t saw_model_name;
|
||||
static Boolean_t saw_function_name;
|
||||
|
||||
static char *dtype_to_str[] = {
|
||||
"BOOLEAN", "INTEGER", "REAL", "COMPLEX", "STRING", "POINTER"
|
||||
};
|
||||
|
||||
static Boolean_t did_default_type;
|
||||
static Boolean_t did_allowed_types;
|
||||
|
||||
static int num_items;
|
||||
static int item;
|
||||
static int item_offset;
|
||||
static Boolean_t num_items_fixed;
|
||||
|
||||
Ifs_Table_t *parser_ifs_table;
|
||||
#define TBL parser_ifs_table
|
||||
|
||||
static int alloced_size [4];
|
||||
|
||||
/*
|
||||
* !!!!! Make sure these are large enough so that they never get realloced
|
||||
* !!!!! since that will cause garbage uninitialized data...
|
||||
* !!!!! (FIX THIS!)
|
||||
*/
|
||||
#define DEFAULT_SIZE_CONN 100
|
||||
#define DEFAULT_SIZE_PARAM 100
|
||||
#define DEFAULT_SIZE_INST_VAR 100
|
||||
#define GROW_SIZE 10
|
||||
|
||||
typedef enum {
|
||||
TBL_NAME,
|
||||
TBL_PORT,
|
||||
TBL_PARAMETER,
|
||||
TBL_STATIC_VAR,
|
||||
} Table_t;
|
||||
|
||||
typedef struct {
|
||||
Table_t table;
|
||||
int record;
|
||||
} Context_t;
|
||||
|
||||
Context_t context;
|
||||
|
||||
#define ITEM_BUFFER_SIZE 20 /* number of items that can be put in a table
|
||||
* before requiring a new xxx_TABLE: keyword
|
||||
*/
|
||||
#define FOR_ITEM(i) for (i = item_offset; i < num_items; i++)
|
||||
#define ITEM_BUF(i) item_buffer[i-item_offset]
|
||||
|
||||
#define ASSIGN_BOUNDS(struct_name, i) \
|
||||
if (ITEM_BUF(i).range.is_named) {\
|
||||
TBL->struct_name[i].has_conn_ref = TRUE;\
|
||||
TBL->struct_name[i].conn_ref = find_conn_ref (ITEM_BUF(i).range.u.name);\
|
||||
} else {\
|
||||
TBL->struct_name[i].has_conn_ref = FALSE;\
|
||||
TBL->struct_name[i].has_lower_bound =\
|
||||
ITEM_BUF(i).range.u.bounds.lower.has_bound;\
|
||||
TBL->struct_name[i].has_upper_bound =\
|
||||
ITEM_BUF(i).range.u.bounds.upper.has_bound;\
|
||||
if (TBL->struct_name[i].has_lower_bound) {\
|
||||
assert (ITEM_BUF(i).range.u.bounds.lower.bound.kind == INTEGER);\
|
||||
TBL->struct_name[i].lower_bound =\
|
||||
ITEM_BUF(i).range.u.bounds.lower.bound.u.ivalue;\
|
||||
}\
|
||||
if (TBL->struct_name[i].has_upper_bound) {\
|
||||
assert (ITEM_BUF(i).range.u.bounds.upper.bound.kind == INTEGER);\
|
||||
TBL->struct_name[i].upper_bound =\
|
||||
ITEM_BUF(i).range.u.bounds.upper.bound.u.ivalue;\
|
||||
}\
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void fatal (char *str)
|
||||
{
|
||||
yyerror (str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int find_conn_ref (name)
|
||||
char *name;
|
||||
{
|
||||
int i;
|
||||
char str[130];
|
||||
|
||||
for (i = 0; i < TBL->num_conn; i++) {
|
||||
if (strcmp (name, TBL->conn[i].name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
sprintf (str, "Port `%s' not found", name);
|
||||
yyerror (str);
|
||||
}
|
||||
|
||||
typedef enum {C_DOUBLE, C_BOOLEAN, C_POINTER, C_UNDEF} Ctype_Class_t;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static Ctype_Class_t get_ctype_class (Port_Type_t type)
|
||||
{
|
||||
switch (type) {
|
||||
case USER_DEFINED:
|
||||
return C_POINTER;
|
||||
break;
|
||||
case DIGITAL:
|
||||
return C_BOOLEAN;
|
||||
break;
|
||||
default:
|
||||
return C_DOUBLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_port_type_direction (Dir_t dir, Port_Type_t port_type)
|
||||
{
|
||||
switch (port_type) {
|
||||
case VOLTAGE:
|
||||
case DIFF_VOLTAGE:
|
||||
case CURRENT:
|
||||
case DIFF_CURRENT:
|
||||
case DIGITAL:
|
||||
case USER_DEFINED:
|
||||
/*
|
||||
* anything goes
|
||||
*/
|
||||
break;
|
||||
case VSOURCE_CURRENT:
|
||||
if (dir != IN) {
|
||||
yyerror ("Port type `vnam' is only valid for `in' ports");
|
||||
}
|
||||
break;
|
||||
case CONDUCTANCE:
|
||||
case DIFF_CONDUCTANCE:
|
||||
case RESISTANCE:
|
||||
case DIFF_RESISTANCE:
|
||||
if (dir != INOUT) {
|
||||
yyerror ("Port types `g', `gd', `h', `hd' are only valid for `inout' ports");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_dtype_not_pointer (Data_Type_t dtype)
|
||||
{
|
||||
if (dtype == POINTER) {
|
||||
yyerror("Invalid parameter type - POINTER type valid only for STATIC_VARs");
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_default_type (Conn_Info_t conn)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < conn.num_allowed_types; i++) {
|
||||
if (conn.default_port_type == conn.allowed_port_type[i]) {
|
||||
if ((conn.default_port_type != USER_DEFINED) ||
|
||||
(strcmp (conn.default_type, conn.allowed_type[i]) == 0)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
yyerror ("Port default type is not an allowed type");
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void assign_ctype_list (conn, ctype_list)
|
||||
Conn_Info_t *conn;
|
||||
Ctype_List_t *ctype_list;
|
||||
{
|
||||
int i;
|
||||
Ctype_List_t *p;
|
||||
Ctype_Class_t class = C_UNDEF;
|
||||
|
||||
conn->num_allowed_types = 0;
|
||||
for (p = ctype_list; p; p = p->next) {
|
||||
conn->num_allowed_types++;
|
||||
}
|
||||
conn->allowed_type = (char**) calloc (conn->num_allowed_types,
|
||||
sizeof (char*));
|
||||
conn->allowed_port_type = (Port_Type_t*) calloc (conn->num_allowed_types,
|
||||
sizeof (Port_Type_t));
|
||||
if (! (conn->allowed_type && conn->allowed_port_type)) {
|
||||
fatal ("Could not allocate memory");
|
||||
}
|
||||
for (i = conn->num_allowed_types-1, p = ctype_list; p; i--, p = p->next) {
|
||||
if (class == C_UNDEF) {
|
||||
class = get_ctype_class (p->ctype.kind);
|
||||
}
|
||||
if (class != get_ctype_class (p->ctype.kind)) {
|
||||
yyerror ("Incompatible port types in `allowed_types' clause");
|
||||
}
|
||||
check_port_type_direction (conn->direction, p->ctype.kind);
|
||||
|
||||
conn->allowed_port_type[i] = p->ctype.kind;
|
||||
conn->allowed_type[i] = p->ctype.id;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void assign_value (type, dest_value, src_value)
|
||||
Data_Type_t type;
|
||||
Value_t *dest_value;
|
||||
My_Value_t src_value;
|
||||
{
|
||||
char str[200];
|
||||
if ((type == REAL) && (src_value.kind == INTEGER)) {
|
||||
dest_value->rvalue = src_value.u.ivalue;
|
||||
return;
|
||||
} else if (type != src_value.kind) {
|
||||
sprintf (str, "Invalid parameter type (saw %s - expected %s)",
|
||||
dtype_to_str[src_value.kind],
|
||||
dtype_to_str[type] );
|
||||
yyerror (str);
|
||||
}
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
dest_value->bvalue = src_value.u.bvalue;
|
||||
break;
|
||||
case INTEGER:
|
||||
dest_value->ivalue = src_value.u.ivalue;
|
||||
break;
|
||||
case REAL:
|
||||
dest_value->rvalue = src_value.u.rvalue;
|
||||
break;
|
||||
case COMPLEX:
|
||||
dest_value->cvalue = src_value.u.cvalue;
|
||||
break;
|
||||
case STRING:
|
||||
dest_value->svalue = src_value.u.svalue;
|
||||
break;
|
||||
default:
|
||||
yyerror ("INTERNAL ERROR - unexpected data type in `assign_value'");
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void assign_limits (type, param, range)
|
||||
Data_Type_t type;
|
||||
Param_Info_t *param;
|
||||
Range_t range;
|
||||
{
|
||||
if (range.is_named) {
|
||||
yyerror ("Named range not allowed for limits");
|
||||
}
|
||||
param->has_lower_limit = range.u.bounds.lower.has_bound;
|
||||
if (param->has_lower_limit) {
|
||||
assign_value (type, ¶m->lower_limit, range.u.bounds.lower.bound);
|
||||
}
|
||||
param->has_upper_limit = range.u.bounds.upper.has_bound;
|
||||
if (param->has_upper_limit) {
|
||||
assign_value (type, ¶m->upper_limit, range.u.bounds.upper.bound);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_item_num ()
|
||||
{
|
||||
if (item-item_offset >= ITEM_BUFFER_SIZE) {
|
||||
fatal ("Too many items in table - split into sub-tables");
|
||||
}
|
||||
if (item > alloced_size [context.table] ) {
|
||||
switch (context.table) {
|
||||
case TBL_NAME:
|
||||
break;
|
||||
case TBL_PORT:
|
||||
alloced_size[context.table] += GROW_SIZE;
|
||||
TBL->conn = (Conn_Info_t*)
|
||||
realloc (TBL->conn,
|
||||
alloced_size [context.table] * sizeof (Conn_Info_t));
|
||||
if (! TBL->conn) {
|
||||
fatal ("Error allocating memory for port definition");
|
||||
}
|
||||
break;
|
||||
case TBL_PARAMETER:
|
||||
alloced_size [context.table] += GROW_SIZE;
|
||||
TBL->param = (Param_Info_t*)
|
||||
realloc (TBL->param,
|
||||
alloced_size [context.table] * sizeof (Param_Info_t));
|
||||
if (! TBL->param) {
|
||||
fatal ("Error allocating memory for parameter definition");
|
||||
}
|
||||
break;
|
||||
case TBL_STATIC_VAR:
|
||||
alloced_size [context.table] += GROW_SIZE;
|
||||
TBL->inst_var = (Inst_Var_Info_t*)
|
||||
realloc (TBL->inst_var,
|
||||
alloced_size [context.table] * sizeof (Inst_Var_Info_t));
|
||||
if (! TBL->inst_var) {
|
||||
fatal ("Error allocating memory for static variable definition");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
item++;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_end_item_num ()
|
||||
{
|
||||
if (num_items_fixed) {
|
||||
if (item != num_items) {
|
||||
char buf[200];
|
||||
sprintf
|
||||
(buf,
|
||||
"Wrong number of elements in sub-table (saw %d - expected %d)",
|
||||
item - item_offset,
|
||||
num_items - item_offset);
|
||||
fatal (buf);
|
||||
}
|
||||
} else {
|
||||
num_items = item;
|
||||
num_items_fixed = TRUE;
|
||||
switch (context.table) {
|
||||
case TBL_NAME:
|
||||
break;
|
||||
case TBL_PORT:
|
||||
TBL->num_conn = num_items;
|
||||
break;
|
||||
case TBL_PARAMETER:
|
||||
TBL->num_param = num_items;
|
||||
break;
|
||||
case TBL_STATIC_VAR:
|
||||
TBL->num_inst_var = num_items;
|
||||
break;
|
||||
}
|
||||
}
|
||||
item = item_offset;
|
||||
}
|
||||
|
||||
#define INIT(n) item = (n); item_offset = (n); num_items = (n); num_items_fixed = FALSE
|
||||
#define ITEM check_item_num()
|
||||
#define END check_end_item_num()
|
||||
|
||||
%}
|
||||
|
||||
%token TOK_ALLOWED_TYPES
|
||||
%token TOK_ARRAY
|
||||
%token TOK_ARRAY_BOUNDS
|
||||
%token TOK_BOOL_NO
|
||||
%token TOK_BOOL_YES
|
||||
%token TOK_COMMA
|
||||
%token TOK_PORT_NAME
|
||||
%token TOK_PORT_TABLE
|
||||
%token TOK_CTYPE_D
|
||||
%token TOK_CTYPE_G
|
||||
%token TOK_CTYPE_GD
|
||||
%token TOK_CTYPE_H
|
||||
%token TOK_CTYPE_HD
|
||||
%token TOK_CTYPE_I
|
||||
%token TOK_CTYPE_ID
|
||||
%token TOK_CTYPE_V
|
||||
%token TOK_CTYPE_VD
|
||||
%token TOK_CTYPE_VNAM
|
||||
%token TOK_C_FUNCTION_NAME
|
||||
%token TOK_DASH
|
||||
%token TOK_DATA_TYPE
|
||||
%token TOK_DEFAULT_TYPE
|
||||
%token TOK_DEFAULT_VALUE
|
||||
%token TOK_DESCRIPTION
|
||||
%token TOK_DIRECTION
|
||||
%token TOK_DIR_IN
|
||||
%token TOK_DIR_INOUT
|
||||
%token TOK_DIR_OUT
|
||||
%token TOK_DTYPE_BOOLEAN
|
||||
%token TOK_DTYPE_COMPLEX
|
||||
%token TOK_DTYPE_INT
|
||||
%token TOK_DTYPE_POINTER
|
||||
%token TOK_DTYPE_REAL
|
||||
%token TOK_DTYPE_STRING
|
||||
%token TOK_IDENTIFIER
|
||||
%token TOK_STATIC_VAR_NAME
|
||||
%token TOK_STATIC_VAR_TABLE
|
||||
%token TOK_INT_LITERAL
|
||||
%token TOK_LANGLE
|
||||
%token TOK_LBRACKET
|
||||
%token TOK_LIMITS
|
||||
%token TOK_NAME_TABLE
|
||||
%token TOK_NULL_ALLOWED
|
||||
%token TOK_PARAMETER_NAME
|
||||
%token TOK_PARAMETER_TABLE
|
||||
%token TOK_RANGLE
|
||||
%token TOK_RBRACKET
|
||||
%token TOK_REAL_LITERAL
|
||||
%token TOK_SPICE_MODEL_NAME
|
||||
%token TOK_STRING_LITERAL
|
||||
|
||||
%union {
|
||||
Ctype_List_t *ctype_list;
|
||||
Dir_t dir;
|
||||
Boolean_t bool;
|
||||
Range_t range;
|
||||
Data_Type_t dtype;
|
||||
My_Port_Type_t ctype;
|
||||
My_Value_t value;
|
||||
char *str;
|
||||
Bound_t bound;
|
||||
int ival;
|
||||
double rval;
|
||||
Complex_t cval;
|
||||
}
|
||||
|
||||
%type <ctype_list> ctype_list delimited_ctype_list
|
||||
%type <dir> direction
|
||||
%type <ctype> ctype
|
||||
%type <dtype> dtype
|
||||
%type <range> range int_range
|
||||
%type <value> value number integer_value value_or_dash
|
||||
%type <str> identifier string
|
||||
%type <bool> bool
|
||||
%type <bound> int_or_dash number_or_dash
|
||||
%type <ival> integer
|
||||
%type <rval> real
|
||||
%type <cval> complex
|
||||
|
||||
%start ifs_file
|
||||
|
||||
%{
|
||||
/*
|
||||
* resuse the Yacc union for our buffer:
|
||||
*/
|
||||
YYSTYPE item_buffer [ITEM_BUFFER_SIZE];
|
||||
|
||||
/*
|
||||
* Shorthand for refering to the current element of the item buffer:
|
||||
*/
|
||||
#define BUF ITEM_BUF(item-1)
|
||||
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
ifs_file : {TBL->num_conn = 0;
|
||||
TBL->num_param = 0;
|
||||
TBL->num_inst_var = 0;
|
||||
|
||||
saw_function_name = FALSE;
|
||||
saw_model_name = FALSE;
|
||||
|
||||
alloced_size [TBL_PORT] = DEFAULT_SIZE_CONN;
|
||||
alloced_size [TBL_PARAMETER] = DEFAULT_SIZE_PARAM;
|
||||
alloced_size [TBL_STATIC_VAR] =
|
||||
DEFAULT_SIZE_INST_VAR;
|
||||
|
||||
TBL->conn = (Conn_Info_t*)
|
||||
calloc (DEFAULT_SIZE_CONN,
|
||||
sizeof (Conn_Info_t));
|
||||
TBL->param = (Param_Info_t*)
|
||||
calloc (DEFAULT_SIZE_PARAM,
|
||||
sizeof (Param_Info_t));
|
||||
TBL->inst_var = (Inst_Var_Info_t*)
|
||||
calloc (DEFAULT_SIZE_INST_VAR,
|
||||
sizeof (Inst_Var_Info_t));
|
||||
if (! (TBL->conn && TBL->param &&
|
||||
TBL->inst_var) ) {
|
||||
fatal ("Could not allocate enough memory");
|
||||
}
|
||||
}
|
||||
list_of_tables
|
||||
;
|
||||
|
||||
list_of_tables : table
|
||||
| list_of_tables table
|
||||
;
|
||||
|
||||
table : TOK_NAME_TABLE
|
||||
{context.table = TBL_NAME;}
|
||||
name_table
|
||||
| TOK_PORT_TABLE
|
||||
{context.table = TBL_PORT;
|
||||
did_default_type = FALSE;
|
||||
did_allowed_types = FALSE;
|
||||
INIT (TBL->num_conn);}
|
||||
port_table
|
||||
{TBL->num_conn = num_items;}
|
||||
| TOK_PARAMETER_TABLE
|
||||
{context.table = TBL_PARAMETER;
|
||||
INIT (TBL->num_param);}
|
||||
parameter_table
|
||||
{TBL->num_param = num_items;}
|
||||
| TOK_STATIC_VAR_TABLE
|
||||
{context.table = TBL_STATIC_VAR;
|
||||
INIT (TBL->num_inst_var);}
|
||||
static_var_table
|
||||
{TBL->num_inst_var = num_items;}
|
||||
;
|
||||
|
||||
name_table : /* empty */
|
||||
| name_table name_table_item
|
||||
;
|
||||
|
||||
name_table_item : TOK_C_FUNCTION_NAME identifier
|
||||
{TBL->name.c_fcn_name =strdup (ifs_yytext);
|
||||
saw_function_name = TRUE;
|
||||
if (parser_just_names && saw_model_name) return 0;}
|
||||
| TOK_SPICE_MODEL_NAME identifier
|
||||
{TBL->name.model_name = strdup (ifs_yytext);
|
||||
saw_model_name = TRUE;
|
||||
if (parser_just_names && saw_function_name) return 0;}
|
||||
| TOK_DESCRIPTION string
|
||||
{TBL->name.description = strdup (ifs_yytext);}
|
||||
;
|
||||
|
||||
port_table : /* empty */
|
||||
| port_table port_table_item
|
||||
;
|
||||
|
||||
port_table_item : TOK_PORT_NAME list_of_ids
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].name = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DESCRIPTION list_of_strings
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].description = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DIRECTION list_of_directions
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].direction = ITEM_BUF(i).dir;
|
||||
}}
|
||||
| TOK_DEFAULT_TYPE list_of_ctypes
|
||||
{int i;
|
||||
END;
|
||||
did_default_type = TRUE;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].default_port_type =
|
||||
ITEM_BUF(i).ctype.kind;
|
||||
TBL->conn[i].default_type = ITEM_BUF(i).ctype.id;
|
||||
if (did_allowed_types) {
|
||||
check_default_type (TBL->conn[i]);
|
||||
}
|
||||
}}
|
||||
| TOK_ALLOWED_TYPES list_of_ctype_lists
|
||||
{int i;
|
||||
END;
|
||||
did_allowed_types = TRUE;
|
||||
FOR_ITEM (i) {
|
||||
assign_ctype_list (&TBL->conn[i],
|
||||
ITEM_BUF(i).ctype_list);
|
||||
if (did_default_type) {
|
||||
check_default_type (TBL->conn[i]);
|
||||
}
|
||||
}}
|
||||
| TOK_ARRAY list_of_bool
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].is_array = ITEM_BUF(i).bool;
|
||||
}}
|
||||
| TOK_ARRAY_BOUNDS list_of_array_bounds
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
ASSIGN_BOUNDS (conn, i);
|
||||
assert (!TBL->conn[i].has_conn_ref);
|
||||
}}
|
||||
| TOK_NULL_ALLOWED list_of_bool
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->conn[i].null_allowed = ITEM_BUF(i).bool;
|
||||
}}
|
||||
;
|
||||
|
||||
parameter_table : /* empty */
|
||||
| parameter_table parameter_table_item
|
||||
;
|
||||
|
||||
parameter_table_item : TOK_PARAMETER_NAME list_of_ids
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->param[i].name = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DESCRIPTION list_of_strings
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->param[i].description = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DATA_TYPE list_of_dtypes
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
check_dtype_not_pointer (ITEM_BUF(i).dtype);
|
||||
TBL->param[i].type = ITEM_BUF(i).dtype;
|
||||
}}
|
||||
| TOK_DEFAULT_VALUE list_of_values
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->param[i].has_default =
|
||||
ITEM_BUF(i).value.has_value;
|
||||
if (TBL->param[i].has_default) {
|
||||
assign_value (TBL->param[i].type,
|
||||
&TBL->param[i].default_value,
|
||||
ITEM_BUF(i).value);
|
||||
}
|
||||
}}
|
||||
| TOK_LIMITS list_of_ranges
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
assign_limits (TBL->param[i].type,
|
||||
&TBL->param[i],
|
||||
ITEM_BUF(i).range);
|
||||
}}
|
||||
| TOK_ARRAY list_of_bool
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->param[i].is_array = ITEM_BUF(i).bool;
|
||||
}}
|
||||
| TOK_ARRAY_BOUNDS list_of_array_bounds
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
ASSIGN_BOUNDS (param, i);
|
||||
}}
|
||||
| TOK_NULL_ALLOWED list_of_bool
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->param[i].null_allowed = ITEM_BUF(i).bool;
|
||||
}}
|
||||
;
|
||||
|
||||
static_var_table : /* empty */
|
||||
| static_var_table static_var_table_item
|
||||
;
|
||||
|
||||
static_var_table_item : TOK_STATIC_VAR_NAME list_of_ids
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->inst_var[i].name = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DESCRIPTION list_of_strings
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->inst_var[i].description = ITEM_BUF(i).str;
|
||||
}}
|
||||
| TOK_DATA_TYPE list_of_dtypes
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->inst_var[i].type = ITEM_BUF(i).dtype;
|
||||
}}
|
||||
| TOK_ARRAY list_of_bool
|
||||
{int i;
|
||||
END;
|
||||
FOR_ITEM (i) {
|
||||
TBL->inst_var[i].is_array = ITEM_BUF(i).bool;
|
||||
}}
|
||||
;
|
||||
|
||||
list_of_ids : /* empty */
|
||||
| list_of_ids identifier {ITEM; BUF.str = $2;}
|
||||
;
|
||||
|
||||
list_of_array_bounds : /* empty */
|
||||
| list_of_array_bounds int_range
|
||||
{ITEM;
|
||||
BUF.range = $2;}
|
||||
| list_of_array_bounds identifier
|
||||
{ITEM;
|
||||
BUF.range.is_named = TRUE;
|
||||
BUF.range.u.name = $2;}
|
||||
;
|
||||
|
||||
list_of_strings : /* empty */
|
||||
| list_of_strings string {ITEM; BUF.str = $2;}
|
||||
;
|
||||
|
||||
list_of_directions : /* empty */
|
||||
| list_of_directions direction {ITEM; BUF.dir = $2;}
|
||||
;
|
||||
|
||||
direction : TOK_DIR_IN {$$ = IN;}
|
||||
| TOK_DIR_OUT {$$ = OUT;}
|
||||
| TOK_DIR_INOUT {$$ = INOUT;}
|
||||
;
|
||||
|
||||
list_of_bool : /* empty */
|
||||
| list_of_bool bool {ITEM; BUF.bool = $2;}
|
||||
;
|
||||
|
||||
list_of_ctypes : /* empty */
|
||||
| list_of_ctypes ctype {ITEM; BUF.ctype = $2;}
|
||||
;
|
||||
|
||||
ctype : TOK_CTYPE_V {$$.kind = VOLTAGE;}
|
||||
| TOK_CTYPE_VD {$$.kind = DIFF_VOLTAGE;}
|
||||
| TOK_CTYPE_VNAM {$$.kind = VSOURCE_CURRENT;}
|
||||
| TOK_CTYPE_I {$$.kind = CURRENT;}
|
||||
| TOK_CTYPE_ID {$$.kind = DIFF_CURRENT;}
|
||||
| TOK_CTYPE_G {$$.kind = CONDUCTANCE;}
|
||||
| TOK_CTYPE_GD {$$.kind = DIFF_CONDUCTANCE;}
|
||||
| TOK_CTYPE_H {$$.kind = RESISTANCE;}
|
||||
| TOK_CTYPE_HD {$$.kind = DIFF_RESISTANCE;}
|
||||
| TOK_CTYPE_D {$$.kind = DIGITAL;}
|
||||
| identifier {$$.kind = USER_DEFINED;
|
||||
$$.id = $1;}
|
||||
;
|
||||
|
||||
list_of_dtypes : /* empty */
|
||||
| list_of_dtypes dtype {ITEM; BUF.dtype = $2;}
|
||||
;
|
||||
|
||||
dtype : TOK_DTYPE_REAL {$$ = REAL;}
|
||||
| TOK_DTYPE_INT {$$ = INTEGER;}
|
||||
| TOK_DTYPE_BOOLEAN {$$ = BOOLEAN;}
|
||||
| TOK_DTYPE_COMPLEX {$$ = COMPLEX;}
|
||||
| TOK_DTYPE_STRING {$$ = STRING;}
|
||||
| TOK_DTYPE_POINTER {$$ = POINTER;}
|
||||
;
|
||||
|
||||
list_of_ranges : /* empty */
|
||||
| list_of_ranges range {ITEM; BUF.range = $2;}
|
||||
;
|
||||
|
||||
int_range : TOK_DASH {$$.is_named = FALSE;
|
||||
$$.u.bounds.lower.has_bound = FALSE;
|
||||
$$.u.bounds.upper.has_bound = FALSE;}
|
||||
| TOK_LBRACKET int_or_dash maybe_comma int_or_dash
|
||||
TOK_RBRACKET
|
||||
{$$.is_named = FALSE;
|
||||
$$.u.bounds.lower = $2;
|
||||
$$.u.bounds.upper = $4;}
|
||||
;
|
||||
|
||||
maybe_comma : /* empty */
|
||||
| TOK_COMMA
|
||||
;
|
||||
|
||||
int_or_dash : TOK_DASH {$$.has_bound = FALSE;}
|
||||
| integer_value {$$.has_bound = TRUE;
|
||||
$$.bound = $1;}
|
||||
;
|
||||
|
||||
range : TOK_DASH {$$.is_named = FALSE;
|
||||
$$.u.bounds.lower.has_bound = FALSE;
|
||||
$$.u.bounds.upper.has_bound = FALSE;}
|
||||
| TOK_LBRACKET number_or_dash maybe_comma
|
||||
number_or_dash TOK_RBRACKET
|
||||
{$$.is_named = FALSE;
|
||||
$$.u.bounds.lower = $2;
|
||||
$$.u.bounds.upper = $4;}
|
||||
;
|
||||
|
||||
number_or_dash : TOK_DASH {$$.has_bound = FALSE;}
|
||||
| number {$$.has_bound = TRUE;
|
||||
$$.bound = $1;}
|
||||
;
|
||||
|
||||
list_of_values : /* empty */
|
||||
| list_of_values value_or_dash {ITEM; BUF.value = $2;}
|
||||
;
|
||||
|
||||
value_or_dash : TOK_DASH {$$.has_value = FALSE;}
|
||||
| value
|
||||
;
|
||||
|
||||
value : string {$$.has_value = TRUE;
|
||||
$$.kind = STRING;
|
||||
$$.u.svalue = $1;}
|
||||
| bool {$$.has_value = TRUE;
|
||||
$$.kind = BOOLEAN;
|
||||
$$.u.bvalue = $1;}
|
||||
| complex {$$.has_value = TRUE;
|
||||
$$.kind = COMPLEX;
|
||||
$$.u.cvalue = $1;}
|
||||
| number
|
||||
;
|
||||
|
||||
complex : TOK_LANGLE real maybe_comma real TOK_RANGLE
|
||||
{$$.real = $2;
|
||||
$$.imag = $4;}
|
||||
;
|
||||
|
||||
list_of_ctype_lists : /* empty */
|
||||
| list_of_ctype_lists delimited_ctype_list
|
||||
{ITEM; BUF.ctype_list = $2;}
|
||||
;
|
||||
|
||||
delimited_ctype_list : TOK_LBRACKET ctype_list TOK_RBRACKET {$$ = $2;}
|
||||
;
|
||||
|
||||
ctype_list : ctype
|
||||
{$$ = (Ctype_List_t*)calloc (1,
|
||||
sizeof (Ctype_List_t));
|
||||
if (!$$) {
|
||||
fatal ("Error allocating memory");
|
||||
}
|
||||
$$->ctype = $1;
|
||||
$$->next = (Ctype_List_t*)0;}
|
||||
| ctype_list maybe_comma ctype
|
||||
{$$ = (Ctype_List_t*)calloc (1,
|
||||
sizeof (Ctype_List_t));
|
||||
if (!$$) {
|
||||
fatal ("Error allocating memory");
|
||||
}
|
||||
$$->ctype = $3;
|
||||
$$->next = $1;
|
||||
/*$$->next = (Ctype_List_t*)0;
|
||||
assert ($1);
|
||||
$1->next = $$;*/}
|
||||
;
|
||||
|
||||
bool : TOK_BOOL_YES {$$ = TRUE;}
|
||||
| TOK_BOOL_NO {$$ = FALSE;}
|
||||
;
|
||||
|
||||
string : TOK_STRING_LITERAL {$$ = strdup(ifs_yytext);}
|
||||
;
|
||||
|
||||
identifier : TOK_IDENTIFIER {$$ = strdup(ifs_yytext);}
|
||||
;
|
||||
|
||||
number : real {$$.has_value = TRUE;
|
||||
$$.kind = REAL;
|
||||
$$.u.rvalue = $1;}
|
||||
| integer_value
|
||||
;
|
||||
|
||||
integer_value : integer {$$.has_value = TRUE;
|
||||
$$.kind = INTEGER;
|
||||
$$.u.ivalue = $1;}
|
||||
;
|
||||
|
||||
real : TOK_REAL_LITERAL {$$ = yydval;}
|
||||
;
|
||||
|
||||
integer : TOK_INT_LITERAL {$$ = yyival;}
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*============================================================================
|
||||
FILE main.c
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the top-level function for the Code Model
|
||||
PreProcessor (cmpp). It handles reading the command-line
|
||||
arguments, and then vectors to an appropriate function.
|
||||
|
||||
INTERFACES
|
||||
|
||||
main()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cmpp.h"
|
||||
|
||||
|
||||
#define USAGE_MSG "Usage: cmpp [-ifs] [-mod [<filename>]] [-lst]"
|
||||
#define TOO_FEW_ARGS "ERROR - Too few arguments"
|
||||
#define TOO_MANY_ARGS "ERROR - Too many arguments"
|
||||
#define UNRECOGNIZED_ARGS "ERROR - Unrecognized argument"
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
main
|
||||
|
||||
Function main checks the validity of the command-line arguments
|
||||
supplied when the program is invoked and calls one of the three
|
||||
major functions as appropriate:
|
||||
|
||||
preprocess_ifs_file Process Interface Specification File.
|
||||
preprocess_mod_file Process Model Definition File.
|
||||
preprocess_lst_file Process Pathname List Files.
|
||||
|
||||
depending on the argument.
|
||||
*/
|
||||
|
||||
main(
|
||||
int argc, /* Number of command line arguments */
|
||||
char *argv[]) /* Command line argument text */
|
||||
{
|
||||
|
||||
init_error (argv[0]);
|
||||
|
||||
/* Process command line arguments and vector to appropriate function */
|
||||
|
||||
if(argc < 2) {
|
||||
print_error(TOO_FEW_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"-ifs") == 0) {
|
||||
if(argc == 2) {
|
||||
preprocess_ifs_file();
|
||||
}
|
||||
else {
|
||||
print_error(TOO_MANY_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1],"-lst") == 0) {
|
||||
if(argc == 2) {
|
||||
preprocess_lst_files();
|
||||
}
|
||||
else {
|
||||
print_error(TOO_MANY_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if(strcmp(argv[1],"-mod") == 0) {
|
||||
if(argc == 2) {
|
||||
preprocess_mod_file("cfunc.mod");
|
||||
}
|
||||
else if(argc == 3) {
|
||||
preprocess_mod_file(argv[2]);
|
||||
}
|
||||
else {
|
||||
print_error(TOO_MANY_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
print_error(UNRECOGNIZED_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
%option yylineno
|
||||
%option noyywrap
|
||||
%array
|
||||
%{ /* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE mod_lex.l
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file defines tokens applicable to parsing the cfunc.mod
|
||||
file, and actions to be taken on encountering those tokens.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
mod_yacc.y
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "mod_yacc.h"
|
||||
#include "mod_tok.h"
|
||||
|
||||
%}
|
||||
|
||||
I [A-Za-z_]
|
||||
Z [0-9A-Za-z_]
|
||||
|
||||
%%
|
||||
|
||||
"/*" {char ch, last_ch;
|
||||
ECHO; /* a comment - repeat it */
|
||||
ch = '\0';
|
||||
do {
|
||||
last_ch = ch;
|
||||
ch = input();
|
||||
fputc(ch,mod_yyout);
|
||||
} while (ch && !((last_ch == '*') && (ch == '/')));
|
||||
if (!ch) {mod_yyerror ("Unterminated comment");}}
|
||||
|
||||
ARGS {return TOK_ARGS;}
|
||||
INIT {return TOK_INIT;}
|
||||
ANALYSIS {return TOK_ANALYSIS;}
|
||||
NEW_TIMEPOINT {return TOK_NEW_TIMEPOINT;}
|
||||
CALL_TYPE {return TOK_CALL_TYPE;}
|
||||
TIME {return TOK_TIME;}
|
||||
RAD_FREQ {return TOK_RAD_FREQ;}
|
||||
TEMPERATURE {return TOK_TEMPERATURE;}
|
||||
T {return TOK_T;}
|
||||
LOAD {return TOK_LOAD;}
|
||||
TOTAL_LOAD {return TOK_TOTAL_LOAD;}
|
||||
MESSAGE {return TOK_MESSAGE;}
|
||||
PARAM {return TOK_PARAM;}
|
||||
PARAM_SIZE {return TOK_PARAM_SIZE;}
|
||||
PARAM_NULL {return TOK_PARAM_NULL;}
|
||||
PORT_SIZE {return TOK_PORT_SIZE;}
|
||||
PORT_NULL {return TOK_PORT_NULL;}
|
||||
PARTIAL {return TOK_PARTIAL;}
|
||||
AC_GAIN {return TOK_AC_GAIN;}
|
||||
OUTPUT_DELAY {return TOK_OUTPUT_DELAY;}
|
||||
STATIC_VAR {return TOK_STATIC_VAR;}
|
||||
STATIC_VAR_SIZE {return TOK_STATIC_VAR_SIZE;}
|
||||
INPUT {return TOK_INPUT;}
|
||||
INPUT_STATE {return TOK_INPUT_STATE;}
|
||||
INPUT_TYPE {return TOK_INPUT_TYPE;}
|
||||
INPUT_STRENGTH {return TOK_INPUT_STRENGTH;}
|
||||
OUTPUT {return TOK_OUTPUT;}
|
||||
OUTPUT_STATE {return TOK_OUTPUT_STATE;}
|
||||
OUTPUT_STRENGTH {return TOK_OUTPUT_STRENGTH;}
|
||||
OUTPUT_TYPE {return TOK_OUTPUT_TYPE;}
|
||||
OUTPUT_CHANGED {return TOK_OUTPUT_CHANGED;}
|
||||
|
||||
"(" {return TOK_LPAREN;}
|
||||
")" {return TOK_RPAREN;}
|
||||
"[" {return TOK_LBRACKET;}
|
||||
"]" {return TOK_RBRACKET;}
|
||||
"," {return TOK_COMMA;}
|
||||
|
||||
{I}+{Z}* {return TOK_IDENTIFIER;}
|
||||
[ \t] ECHO; /* just eat non-newline whitespace */
|
||||
\n ECHO; /* echo newlines */
|
||||
. {return TOK_MISC_C;}
|
||||
|
||||
%%
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE mod_yacc.h
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
Typedefs needed by the YYSTYPE union (%union operator) in the yacc
|
||||
file. These are only used in the yacc file, but must be defined here since
|
||||
the generated token.h file includes a definition of the union YYSTYPE.
|
||||
|
||||
INTERFACES
|
||||
|
||||
None.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "cmpp.h"
|
||||
|
||||
typedef struct {
|
||||
char *id;
|
||||
Boolean_t has_subscript;
|
||||
char *subscript;
|
||||
} Sub_Id_t;
|
||||
|
|
@ -0,0 +1,566 @@
|
|||
%{ /* $Id$ */
|
||||
|
||||
/*============================================================================
|
||||
FILE mod_yacc.y
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains a BNF specification of the translation of
|
||||
cfunc.mod files to cfunc.c files, together with various support
|
||||
functions.
|
||||
|
||||
INTERFACES
|
||||
|
||||
mod_yyparse() - Function 'yyparse()' is generated automatically
|
||||
by UNIX 'yacc' utility and then converted to
|
||||
'mod_yyparse()' by UNIX 'sed' utility under
|
||||
direction of Makefile.
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
mod_lex.l
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
Names of functions generated by 'yacc' are translated by 'sed'
|
||||
under direction of the Makefile to prevent collisions with
|
||||
functions generated from ifs_yacc.y.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "mod_yacc.h"
|
||||
|
||||
Ifs_Table_t *mod_ifs_table;
|
||||
|
||||
extern char mod_yytext[];
|
||||
extern FILE* mod_yyout;
|
||||
|
||||
/* saj - use standard includes */
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
/*
|
||||
extern char *strdup(char*);
|
||||
extern int strlen(char*);
|
||||
extern char *strcat(char*, char*);
|
||||
*/
|
||||
|
||||
int mod_num_errors;
|
||||
|
||||
#define BUFFER_SIZE 3000
|
||||
static char buffer [BUFFER_SIZE];
|
||||
static int buf_len;
|
||||
|
||||
typedef enum {CONN, PARAM, STATIC_VAR} Id_Kind_t;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static char *subscript (Sub_Id_t sub_id)
|
||||
{
|
||||
if (sub_id.has_subscript) {
|
||||
return sub_id.subscript;
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int strcmpi(s, t)
|
||||
char *s;
|
||||
char *t;
|
||||
/* string compare - case insensitive */
|
||||
{
|
||||
for (; *s && t && tolower(*s) == tolower(*t); s++, t++);
|
||||
if (*s && !*t) {
|
||||
return 1;
|
||||
}
|
||||
if (!*s && *t) {
|
||||
return -1;
|
||||
}
|
||||
if (! (*s || *t)) {
|
||||
return 0;
|
||||
}
|
||||
return (tolower(*s) - tolower(*t));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void put_type (FILE *fp, Data_Type_t type)
|
||||
{
|
||||
char ch;
|
||||
|
||||
switch (type) {
|
||||
case INTEGER:
|
||||
ch = 'i';
|
||||
break;
|
||||
case REAL:
|
||||
ch = 'r';
|
||||
break;
|
||||
case COMPLEX:
|
||||
ch = 'c';
|
||||
break;
|
||||
case BOOLEAN:
|
||||
ch = 'b';
|
||||
break;
|
||||
case STRING:
|
||||
ch = 's';
|
||||
break;
|
||||
case POINTER:
|
||||
ch = 'p';
|
||||
break;
|
||||
}
|
||||
fprintf (fp, ".%cvalue", ch);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void put_conn_type (FILE *fp, Port_Type_t type)
|
||||
{
|
||||
char ch;
|
||||
|
||||
switch (type) {
|
||||
case USER_DEFINED:
|
||||
ch = 'p';
|
||||
break;
|
||||
case DIGITAL:
|
||||
ch = 'p';
|
||||
break;
|
||||
default:
|
||||
ch = 'r';
|
||||
break;
|
||||
}
|
||||
fprintf (fp, ".%cvalue", ch);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_dir (int conn_number, Dir_t dir, char *context)
|
||||
{
|
||||
Dir_t conn_dir;
|
||||
|
||||
if (conn_number >= 0) {
|
||||
/*
|
||||
* If negative, this is an invalid port ID and we've already issued
|
||||
* an error.
|
||||
*/
|
||||
conn_dir = mod_ifs_table->conn[conn_number].direction;
|
||||
if ((conn_dir != dir) && (conn_dir != INOUT)) {
|
||||
char error_str[200];
|
||||
|
||||
sprintf (error_str,
|
||||
"Direction of port `%s' in %s() is not %s or INOUT",
|
||||
mod_ifs_table->conn[conn_number].name, context,
|
||||
(dir == IN) ? "IN" : "OUT");
|
||||
yyerror (error_str);
|
||||
mod_num_errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void check_subscript (Boolean_t formal, Boolean_t actual,
|
||||
Boolean_t missing_actual_ok,
|
||||
char *context, char *id)
|
||||
{
|
||||
char error_str[200];
|
||||
|
||||
if ((formal && !actual) && !missing_actual_ok) {
|
||||
sprintf (error_str,
|
||||
"%s `%s' is an array - subscript required",
|
||||
context, id);
|
||||
yyerror (error_str);
|
||||
mod_num_errors++;
|
||||
return;
|
||||
} else if (!formal && actual) {
|
||||
sprintf (error_str,
|
||||
"%s `%s' is not an array - subscript prohibited",
|
||||
context, id);
|
||||
yyerror (error_str);
|
||||
mod_num_errors++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int check_id (Sub_Id_t sub_id, Id_Kind_t kind, Boolean_t do_subscript)
|
||||
{
|
||||
int i;
|
||||
char error_str[200];
|
||||
|
||||
switch (kind) {
|
||||
case CONN:
|
||||
for (i = 0; i < mod_ifs_table->num_conn; i++) {
|
||||
if (0 == strcmpi (sub_id.id, mod_ifs_table->conn[i].name)) {
|
||||
if (do_subscript) {
|
||||
check_subscript (mod_ifs_table->conn[i].is_array,
|
||||
sub_id.has_subscript, FALSE, "Port",
|
||||
sub_id.id);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PARAM:
|
||||
for (i = 0; i < mod_ifs_table->num_param; i++) {
|
||||
if (0 == strcmpi (sub_id.id, mod_ifs_table->param[i].name)) {
|
||||
if (do_subscript) {
|
||||
check_subscript (mod_ifs_table->param[i].is_array,
|
||||
sub_id.has_subscript, FALSE, "Parameter",
|
||||
sub_id.id);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATIC_VAR:
|
||||
for (i = 0; i < mod_ifs_table->num_inst_var; i++) {
|
||||
if (0 == strcmpi (sub_id.id, mod_ifs_table->inst_var[i].name)) {
|
||||
if (do_subscript) {
|
||||
check_subscript (mod_ifs_table->inst_var[i].is_array,
|
||||
sub_id.has_subscript, TRUE,
|
||||
"Static Variable",
|
||||
sub_id.id);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sprintf (error_str, "No %s named '%s'",
|
||||
((kind==CONN)
|
||||
? "port"
|
||||
: ((kind==PARAM)
|
||||
? "parameter"
|
||||
:"static variable")),
|
||||
sub_id.id);
|
||||
yyerror (error_str);
|
||||
mod_num_errors++;
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int valid_id (Sub_Id_t sub_id, Id_Kind_t kind)
|
||||
{
|
||||
return check_id (sub_id, kind, FALSE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int valid_subid (Sub_Id_t sub_id, Id_Kind_t kind)
|
||||
{
|
||||
return check_id (sub_id, kind, TRUE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static init_buffer ()
|
||||
{
|
||||
buf_len = 0;
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static append (char *str)
|
||||
{
|
||||
int len = strlen (str);
|
||||
if (len + buf_len > BUFFER_SIZE) {
|
||||
yyerror ("Buffer overflow - try reducing the complexity of CM-macro array subscripts");
|
||||
exit (1);
|
||||
}
|
||||
(void)strcat (buffer,str);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *str;
|
||||
Sub_Id_t sub_id;
|
||||
}
|
||||
|
||||
%type <str> buffered_c_code
|
||||
%type <sub_id> subscriptable_id id
|
||||
|
||||
%token TOK_ARGS
|
||||
%token TOK_INIT
|
||||
%token TOK_ANALYSIS
|
||||
%token TOK_NEW_TIMEPOINT
|
||||
%token TOK_TIME
|
||||
%token TOK_RAD_FREQ
|
||||
%token TOK_TEMPERATURE
|
||||
%token TOK_T
|
||||
%token TOK_PARAM
|
||||
%token TOK_PARAM_SIZE
|
||||
%token TOK_PARAM_NULL
|
||||
%token TOK_PORT_SIZE
|
||||
%token TOK_PORT_NULL
|
||||
%token TOK_PARTIAL
|
||||
%token TOK_AC_GAIN
|
||||
%token TOK_CHANGED
|
||||
%token TOK_OUTPUT_DELAY
|
||||
%token TOK_STATIC_VAR
|
||||
%token TOK_STATIC_VAR_SIZE
|
||||
%token TOK_INPUT
|
||||
%token TOK_INPUT_STRENGTH
|
||||
%token TOK_INPUT_STATE
|
||||
%token TOK_INPUT_TYPE
|
||||
%token TOK_OUTPUT
|
||||
%token TOK_OUTPUT_CHANGED
|
||||
%token TOK_OUTPUT_STRENGTH
|
||||
%token TOK_OUTPUT_STATE
|
||||
%token TOK_OUTPUT_TYPE
|
||||
%token TOK_COMMA
|
||||
%token TOK_LPAREN
|
||||
%token TOK_RPAREN
|
||||
%token TOK_LBRACKET
|
||||
%token TOK_RBRACKET
|
||||
%token TOK_MISC_C
|
||||
%token TOK_IDENTIFIER
|
||||
%token TOK_LOAD
|
||||
%token TOK_TOTAL_LOAD
|
||||
%token TOK_MESSAGE
|
||||
%token TOK_CALL_TYPE
|
||||
|
||||
%start mod_file
|
||||
|
||||
%%
|
||||
|
||||
mod_file : /* empty */
|
||||
| mod_file c_code
|
||||
;
|
||||
|
||||
c_code : /* empty */
|
||||
| c_code c_char
|
||||
| c_code macro
|
||||
/*| TOK_RPAREN {yyerror ("Unmatched )"); YYERROR;}
|
||||
| TOK_RBRACKET {yyerror ("Unmatched ]"); YYERROR;}*/
|
||||
;
|
||||
|
||||
buffered_c_code : {init_buffer();} buffered_c_code2
|
||||
{$$ = strdup (buffer);}
|
||||
;
|
||||
|
||||
buffered_c_code2 : /* empty */
|
||||
| buffered_c_code2 buffered_c_char
|
||||
;
|
||||
|
||||
buffered_c_char : TOK_IDENTIFIER {append (mod_yytext);}
|
||||
| TOK_MISC_C {append (mod_yytext);}
|
||||
| TOK_COMMA {append (mod_yytext);}
|
||||
| TOK_LBRACKET
|
||||
{append("[");}
|
||||
buffered_c_code2 TOK_RBRACKET
|
||||
{append("]");}
|
||||
| TOK_LPAREN
|
||||
{append("(");}
|
||||
buffered_c_code2 TOK_RPAREN
|
||||
{append(")");}
|
||||
;
|
||||
|
||||
c_char : TOK_IDENTIFIER {fputs (mod_yytext, mod_yyout);}
|
||||
| TOK_MISC_C {fputs (mod_yytext, mod_yyout);}
|
||||
| TOK_COMMA {fputs (mod_yytext, mod_yyout);}
|
||||
| TOK_LBRACKET
|
||||
{putc ('[', mod_yyout);}
|
||||
c_code TOK_RBRACKET
|
||||
{putc (']', mod_yyout);}
|
||||
| TOK_LPAREN
|
||||
{putc ('(', mod_yyout);}
|
||||
c_code TOK_RPAREN
|
||||
{putc (')', mod_yyout);}
|
||||
;
|
||||
|
||||
macro : TOK_INIT
|
||||
{fprintf (mod_yyout, "private->circuit.init");}
|
||||
| TOK_ARGS
|
||||
{fprintf (mod_yyout, "Mif_Private_t *private");}
|
||||
| TOK_ANALYSIS
|
||||
{fprintf (mod_yyout, "private->circuit.anal_type");}
|
||||
| TOK_NEW_TIMEPOINT
|
||||
{fprintf (mod_yyout, "private->circuit.anal_init");}
|
||||
| TOK_CALL_TYPE
|
||||
{fprintf (mod_yyout, "private->circuit.call_type");}
|
||||
| TOK_TIME
|
||||
{fprintf (mod_yyout, "private->circuit.time");}
|
||||
| TOK_RAD_FREQ
|
||||
{fprintf (mod_yyout, "private->circuit.frequency");}
|
||||
| TOK_TEMPERATURE
|
||||
{fprintf (mod_yyout, "private->circuit.temperature");}
|
||||
| TOK_T TOK_LPAREN buffered_c_code TOK_RPAREN
|
||||
{fprintf (mod_yyout, "private->circuit.t[%s]", $3);}
|
||||
| TOK_PARAM TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, PARAM);
|
||||
fprintf (mod_yyout, "private->param[%d]->element[%s]",
|
||||
i, subscript ($3));
|
||||
put_type (mod_yyout, mod_ifs_table->param[i].type);
|
||||
}
|
||||
| TOK_PARAM_SIZE TOK_LPAREN id TOK_RPAREN
|
||||
{int i = valid_id ($3, PARAM);
|
||||
fprintf (mod_yyout, "private->param[%d]->size", i);}
|
||||
| TOK_PARAM_NULL TOK_LPAREN id TOK_RPAREN
|
||||
{int i = valid_id ($3, PARAM);
|
||||
fprintf (mod_yyout, "private->param[%d]->is_null", i);}
|
||||
| TOK_PORT_SIZE TOK_LPAREN id TOK_RPAREN
|
||||
{int i = valid_id ($3, CONN);
|
||||
fprintf (mod_yyout, "private->conn[%d]->size", i);}
|
||||
| TOK_PORT_NULL TOK_LPAREN id TOK_RPAREN
|
||||
{int i = valid_id ($3, CONN);
|
||||
fprintf (mod_yyout, "private->conn[%d]->is_null", i);}
|
||||
| TOK_PARTIAL TOK_LPAREN subscriptable_id TOK_COMMA
|
||||
subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
int j = valid_subid ($5, CONN);
|
||||
check_dir (i, OUT, "PARTIAL");
|
||||
check_dir (j, IN, "PARTIAL");
|
||||
fprintf (mod_yyout, "private->conn[%d]->port[%s]->partial[%d].port[%s]",
|
||||
i, subscript($3), j, subscript($5));}
|
||||
| TOK_AC_GAIN TOK_LPAREN subscriptable_id TOK_COMMA
|
||||
subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
int j = valid_subid ($5, CONN);
|
||||
check_dir (i, OUT, "AC_GAIN");
|
||||
check_dir (j, IN, "AC_GAIN");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->ac_gain[%d].port[%s]",
|
||||
i, subscript($3), j, subscript($5));}
|
||||
| TOK_STATIC_VAR TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, STATIC_VAR);
|
||||
fprintf (mod_yyout,
|
||||
"private->inst_var[%d]->element[%s]",
|
||||
i, subscript($3));
|
||||
if (mod_ifs_table->inst_var[i].is_array
|
||||
&& !($3.has_subscript)) {
|
||||
/* null - eg. for malloc lvalue */
|
||||
} else {
|
||||
put_type (mod_yyout,
|
||||
mod_ifs_table->inst_var[i].type);
|
||||
} }
|
||||
| TOK_STATIC_VAR_SIZE TOK_LPAREN id TOK_RPAREN
|
||||
{int i = valid_subid ($3, STATIC_VAR);
|
||||
fprintf (mod_yyout, "private->inst_var[%d]->size",
|
||||
i, subscript($3));}
|
||||
| TOK_OUTPUT_DELAY TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "OUTPUT_DELAY");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->delay", i,
|
||||
subscript($3));}
|
||||
| TOK_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "CHANGED");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->changed", i,
|
||||
subscript($3));}
|
||||
| TOK_INPUT TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, IN, "INPUT");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->input",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);}
|
||||
| TOK_INPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, IN, "INPUT_TYPE");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->type_str",
|
||||
i, subscript($3)); }
|
||||
| TOK_OUTPUT_TYPE TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "OUTPUT_TYPE");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->type_str",
|
||||
i, subscript($3)); }
|
||||
| TOK_INPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, IN, "INPUT_STRENGTH");
|
||||
fprintf (mod_yyout,
|
||||
"((Digital_t*)(private->conn[%d]->port[%s]->input",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);
|
||||
fprintf (mod_yyout, "))->strength");}
|
||||
| TOK_INPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, IN, "INPUT_STATE");
|
||||
fprintf (mod_yyout,
|
||||
"((Digital_t*)(private->conn[%d]->port[%s]->input",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);
|
||||
fprintf (mod_yyout, "))->state");}
|
||||
| TOK_OUTPUT TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "OUTPUT");
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->output",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);}
|
||||
| TOK_OUTPUT_STRENGTH TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "OUTPUT_STRENGTH");
|
||||
fprintf (mod_yyout,
|
||||
"((Digital_t*)(private->conn[%d]->port[%s]->output",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);
|
||||
fprintf (mod_yyout, "))->strength");}
|
||||
| TOK_OUTPUT_STATE TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
check_dir (i, OUT, "OUTPUT_STATE");
|
||||
fprintf (mod_yyout,
|
||||
"((Digital_t*)(private->conn[%d]->port[%s]->output",
|
||||
i, subscript($3));
|
||||
put_conn_type (mod_yyout,
|
||||
mod_ifs_table->conn[i].allowed_port_type[0]);
|
||||
fprintf (mod_yyout, "))->state");}
|
||||
| TOK_OUTPUT_CHANGED TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->changed", i,
|
||||
subscript($3));}
|
||||
| TOK_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->load", i,
|
||||
subscript($3));}
|
||||
| TOK_TOTAL_LOAD TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->total_load", i,
|
||||
subscript($3));}
|
||||
| TOK_MESSAGE TOK_LPAREN subscriptable_id TOK_RPAREN
|
||||
{int i = valid_subid ($3, CONN);
|
||||
fprintf (mod_yyout,
|
||||
"private->conn[%d]->port[%s]->msg", i,
|
||||
subscript($3));}
|
||||
;
|
||||
|
||||
subscriptable_id : id
|
||||
| id TOK_LBRACKET buffered_c_code TOK_RBRACKET
|
||||
{$$ = $1;
|
||||
$$.has_subscript = TRUE;
|
||||
$$.subscript = $3;}
|
||||
;
|
||||
|
||||
id : TOK_IDENTIFIER
|
||||
{$$.has_subscript = FALSE;
|
||||
$$.id = strdup (mod_yytext);}
|
||||
;
|
||||
|
||||
%%
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*============================================================================
|
||||
FILE pp_ifs.c
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the main function for processing an Interface Spec
|
||||
File (ifspec.ifs).
|
||||
|
||||
INTERFACES
|
||||
|
||||
preprocess_ifs_file()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "cmpp.h"
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
preprocess_ifs_file
|
||||
|
||||
Function preprocess_ifs_file is the top-level driver function for
|
||||
preprocessing an Interface Specification file (ifspec.ifs). This
|
||||
function calls read_ifs_file() requesting it to read and parse
|
||||
the Interface Specification file and place the information
|
||||
contained in it into an internal data structure. Then
|
||||
write_ifs_c_file() is called to write the information out in a C
|
||||
file that will be compiled and linked with the simulator.
|
||||
*/
|
||||
|
||||
|
||||
void preprocess_ifs_file(void)
|
||||
{
|
||||
|
||||
Ifs_Table_t ifs_table; /* Repository for info read from ifspec.ifs file */
|
||||
|
||||
Status_t status; /* Return status */
|
||||
|
||||
|
||||
/* Read the entire ifspec.ifs file and load the data into ifs_table */
|
||||
|
||||
status = read_ifs_file(IFSPEC_FILENAME,GET_IFS_TABLE,&ifs_table);
|
||||
|
||||
if(status != OK) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* Write the ifspec.c file required by the spice simulator */
|
||||
|
||||
status = write_ifs_c_file("ifspec.c",&ifs_table);
|
||||
|
||||
if(status != OK) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,180 @@
|
|||
/*============================================================================
|
||||
FILE pp_mod.c
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the top-level driver function for preprocessing the
|
||||
"cfunc.mod" file. First, the "ifspec.ifs" file is opened and parsed to
|
||||
get the data that will be needed in the .mod to .c translation (See
|
||||
read_ifs.c). Then the .mod file is translated. Most of the work of the
|
||||
translation is handled by the UNIX 'lex' and 'yacc' utilities. This
|
||||
translation is begun at the call to mod_yyparse() below. See also files:
|
||||
|
||||
mod_lex.l
|
||||
mod_yacc.y
|
||||
|
||||
Note that to allow lex/yacc to be used twice (once for the ifspec.ifs
|
||||
file, and then again for the cfunc.mod file), the functions created by
|
||||
lex/yacc for the latter are translated using the UNIX text editor 'sed'
|
||||
under the direction of the Makefile and the following 'sed scripts':
|
||||
|
||||
mod_lex.sed
|
||||
mod_yacc.sed
|
||||
|
||||
Hence the call to 'mod_yyparse()' rather than 'yyparse()' below.
|
||||
|
||||
INTERFACES
|
||||
|
||||
preprocess_mod_file()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "cmpp.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void change_extension (char *filename, char *ext, char *new_filename)
|
||||
{
|
||||
int i = strlen (filename);
|
||||
|
||||
strcpy (new_filename, filename);
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
if (new_filename[i] == '.') {
|
||||
new_filename[i+1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
strcat (new_filename, ext);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
preprocess_mod_file
|
||||
|
||||
Function preprocess_mod_file is the top-level driver function for
|
||||
preprocessing a code model file (cfunc.mod). This function calls
|
||||
read_ifs_file() requesting it to read and parse the Interface
|
||||
Specification file (ifspec.ifs) and place the information
|
||||
contained in it into an internal data structure. It then calls
|
||||
mod_yyparse() to read the cfunc.mod file and translate it
|
||||
according to the Interface Specification information. Function
|
||||
mod_yyparse() is automatically generated by UNIX lex/yacc
|
||||
utilities.
|
||||
*/
|
||||
|
||||
|
||||
void preprocess_mod_file (
|
||||
char *filename) /* The file to read */
|
||||
{
|
||||
extern FILE *mod_yyin;
|
||||
extern FILE *mod_yyout;
|
||||
extern char *current_filename;
|
||||
extern int mod_yylineno;
|
||||
extern int mod_num_errors;
|
||||
extern Ifs_Table_t *mod_ifs_table;
|
||||
|
||||
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
|
||||
Status_t status; /* Return status */
|
||||
char error_str[200];
|
||||
char output_filename[200];
|
||||
|
||||
/*
|
||||
* Read the entire ifspec.ifs file and load the data into ifs_table
|
||||
*/
|
||||
|
||||
status = read_ifs_file (IFSPEC_FILENAME, GET_IFS_TABLE, &ifs_table);
|
||||
|
||||
if (status != OK) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mod_yyin = fopen (filename, "r");
|
||||
if (mod_yyin == NULL) {
|
||||
sprintf(error_str, "ERROR - Could not open input .mod file: %s",
|
||||
filename);
|
||||
print_error(error_str);
|
||||
return;
|
||||
}
|
||||
|
||||
current_filename = filename;
|
||||
|
||||
change_extension (filename, "c", output_filename);
|
||||
mod_yyout = fopen (output_filename, "w");
|
||||
|
||||
if (mod_yyout == NULL) {
|
||||
sprintf(error_str, "ERROR - Could not open output .c: %s",
|
||||
output_filename);
|
||||
print_error(error_str);
|
||||
return;
|
||||
}
|
||||
|
||||
mod_ifs_table = &ifs_table;
|
||||
mod_num_errors = 0;
|
||||
|
||||
fprintf (mod_yyout, "#line 1 \"%s\"\n", filename);
|
||||
fprintf (mod_yyout, "#include \"cm.h\"\n");
|
||||
fprintf (mod_yyout, "#line 1 \"%s\"\n", filename);
|
||||
|
||||
mod_yylineno = 1;
|
||||
if (!mod_yyin) {
|
||||
sprintf (error_str, "Could not open .mod file: \"%s\"", filename);
|
||||
print_error (error_str);
|
||||
unlink (output_filename);
|
||||
exit(1);
|
||||
}
|
||||
if (!mod_yyout) {
|
||||
sprintf (error_str, "Could not create .c file: \"%s\"",
|
||||
output_filename);
|
||||
print_error (error_str);
|
||||
unlink (output_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (mod_yyparse() || (mod_num_errors > 0)) {
|
||||
sprintf (error_str, "Error parsing .mod file: \"%s\"", filename);
|
||||
print_error (error_str);
|
||||
unlink (output_filename);
|
||||
exit (1);
|
||||
}
|
||||
fclose (mod_yyout);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int mod_yyerror (str)
|
||||
char *str;
|
||||
{
|
||||
extern int mod_yylineno;
|
||||
extern char mod_yytext[];
|
||||
extern char *current_filename;
|
||||
extern char *prog_name;
|
||||
|
||||
fprintf (stderr, "%s: Error: \"%s\": line %d (near \'%s\'):\n\t%s.\n",
|
||||
prog_name, current_filename, mod_yylineno, mod_yytext, str);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*============================================================================
|
||||
FILE read_ifs.c
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn and Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains top-level functions used in reading information
|
||||
from the ifspec.ifs file and building an internal data structure that
|
||||
holds the information. Most of the work in parsing of the
|
||||
ifspec.ifs file and in building the structure is handled by
|
||||
the UNIX 'lex' and 'yacc' utilities. This processing is begun
|
||||
at the call to yyparse() in read_ifs_table() below. See also files:
|
||||
|
||||
ifs_lex.l
|
||||
ifs_yacc.y
|
||||
|
||||
INTERFACES
|
||||
|
||||
read_ifs_file()
|
||||
yywrap()
|
||||
yyerror()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include "cmpp.h"
|
||||
|
||||
extern char *prog_name;
|
||||
|
||||
void *malloc(unsigned size);
|
||||
|
||||
static Status_t read_ifs_table(FILE *fp, int mode, Ifs_Table_t *ifs_table);
|
||||
|
||||
char *current_filename;
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
NOTE
|
||||
|
||||
The following function may be called either by cmpp -ifs or cmpp -lst with
|
||||
mode set to GET_IFS_TABLE or GET_IFS_NAME respectively.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
read_ifs_file
|
||||
|
||||
Function read_ifs_file() opens the Interface Specification file
|
||||
(ifspec.ifs) for read access and calls read_ifs_table() with the
|
||||
assigned file pointer to read and parse the file. Upon return
|
||||
from read_ifs_table(), the file is closed.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
Status_t read_ifs_file(
|
||||
char *filename, /* File to read */
|
||||
int mode, /* Get names only or get everything? */
|
||||
Ifs_Table_t *ifs_table) /* Table to put info in */
|
||||
{
|
||||
|
||||
FILE *fp; /* Ifs file pointer */
|
||||
|
||||
char msg[MAX_PATH_LEN+257]; /* space for an error message */
|
||||
|
||||
Status_t status; /* returned status from function */
|
||||
|
||||
|
||||
/* Open the ifs file for read access */
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
|
||||
if(fp == NULL) {
|
||||
perror (prog_name);
|
||||
sprintf(msg, "ERROR - File not found: %s", filename);
|
||||
print_error(msg);
|
||||
return(ERROR);
|
||||
}
|
||||
|
||||
current_filename = filename;
|
||||
|
||||
/* Get the stuff from the file into the ifs_table struct */
|
||||
|
||||
status = read_ifs_table(fp, mode, ifs_table);
|
||||
|
||||
/* Close file and return */
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return(status);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
read_ifs_table
|
||||
|
||||
Function read_ifs_table() calls yyparse() to read and parse the
|
||||
Interface Specification file contents and place the information
|
||||
into an internal data structure. Function yyparse() is
|
||||
automatically generated by UNIX lex/yacc.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static Status_t read_ifs_table(
|
||||
FILE *fp, /* File to read from */
|
||||
int mode, /* Get names only or get everything? */
|
||||
Ifs_Table_t *ifs_table) /* Table to put info in */
|
||||
{
|
||||
|
||||
extern FILE *ifs_yyin;
|
||||
extern Ifs_Table_t *parser_ifs_table;
|
||||
extern Boolean_t parser_just_names;
|
||||
extern int ifs_yylineno;
|
||||
|
||||
assert (ifs_table);
|
||||
assert (fp);
|
||||
|
||||
ifs_yylineno = 1;
|
||||
ifs_yyin = fp;
|
||||
parser_just_names = (mode == GET_IFS_NAME);
|
||||
parser_ifs_table = ifs_table;
|
||||
|
||||
if (ifs_yyparse()) {
|
||||
print_error ("Error parsing interface specification file");
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int ifs_yyerror (str)
|
||||
char *str;
|
||||
{
|
||||
extern int ifs_yylineno;
|
||||
extern char ifs_yytext[];
|
||||
|
||||
fprintf (stderr, "%s: Error: \"%s\": line %d (near \'%s\'):\n\t%s.\n",
|
||||
prog_name, current_filename, ifs_yylineno, ifs_yytext, str);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*============================================================================
|
||||
FILE util.c
|
||||
|
||||
MEMBER OF process cmpp
|
||||
|
||||
Copyright 1991
|
||||
Georgia Tech Research Corporation
|
||||
Atlanta, Georgia 30332
|
||||
All Rights Reserved
|
||||
|
||||
PROJECT A-8503
|
||||
|
||||
AUTHORS
|
||||
|
||||
9/12/91 Bill Kuhn and Steve Tynor
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
<date> <person name> <nature of modifications>
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains miscellaneous utility functions used in cmpp.
|
||||
|
||||
INTERFACES
|
||||
|
||||
init_error()
|
||||
print_error()
|
||||
str_to_lower()
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
None.
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
|
||||
#include "cmpp.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
char *prog_name;
|
||||
|
||||
|
||||
/* Initialize print_error() with the name of the program */
|
||||
|
||||
void init_error (char *program_name)
|
||||
{
|
||||
prog_name = program_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print an error message to stderr */
|
||||
|
||||
void print_error(
|
||||
char *msg) /* The message to write */
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", prog_name, msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convert a string to all lower case */
|
||||
|
||||
str_to_lower(s)
|
||||
|
||||
char *s; /* The string to convert */
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for(i = 0; (c = s[i]) != '\0'; i++)
|
||||
if(isalpha(c))
|
||||
if(isupper(c))
|
||||
s[i] = tolower(c);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue