home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftptest.leeds.ac.uk
/
2015.02.ftptest.leeds.ac.uk.tar
/
ftptest.leeds.ac.uk
/
bionet
/
CAE-GROUP
/
SCL-WIN3x
/
FED_PLUS.EXE
/
LEXACT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-25
|
14KB
|
543 lines
static char rcsid[] = "$Id: lexact.c,v 1.3 1994/05/11 19:51:24 libes Exp $";
/*
* This software was developed by U.S. Government employees as part of
* their official duties and is not subject to copyright.
*
* $Log: lexact.c,v $
* Revision 1.3 1994/05/11 19:51:24 libes
* numerous fixes
*
* Revision 1.2 1993/10/15 18:48:48 libes
* CADDETC certified
*
* Revision 1.7 1993/02/22 21:48:00 libes
* added decl for strdup
*
* Revision 1.6 1993/01/19 22:44:17 libes
* *** empty log message ***
*
* Revision 1.5 1992/08/27 23:40:58 libes
* remove connection between scanner and rest of EXPRESSinitializations
*
* Revision 1.4 1992/08/18 17:13:43 libes
* rm'd extraneous error messages
*
* Revision 1.3 1992/06/08 18:06:57 libes
* prettied up interface to print_objects_when_running
*/
#define LEXACT_C
#include <ctype.h>
#include "lexact.h"
#include <string.h>
#include "linklist.h"
#include "stack.h"
#include "hash.h"
#include "express.h"
#include "expparse.h"
#include "dict.h"
#include "memory.h"
extern int yylineno;
extern exp_YYSTYPE exp_yylval;
extern FILE* yyin;
#ifdef FLEX
extern char* exp_yytext;
#else /* LEX */
extern char exp_yytext[];
#endif /*FLEX*/
#if 0
static Hash_Table macros;
#endif
/* keyword lookup table */
static Hash_Table keyword_dictionary;
static struct keyword_entry {
char *key;
int token;
} keywords[] = {
{ "ABS", TOK_BUILTIN_FUNCTION },
{ "ABSTRACT", TOK_ABSTRACT },
{ "ACOS", TOK_BUILTIN_FUNCTION },
{ "AGGREGATE", TOK_AGGREGATE },
{ "ALIAS", TOK_ALIAS },
{ "AND", TOK_AND },
{ "ANDOR", TOK_ANDOR },
{ "ARRAY", TOK_ARRAY },
{ "AS", TOK_AS },
{ "ASIN", TOK_BUILTIN_FUNCTION },
{ "ATAN", TOK_BUILTIN_FUNCTION },
{ "BAG", TOK_BAG },
{ "BEGIN", TOK_BEGIN },
{ "BINARY", TOK_BINARY },
{ "BLENGTH", TOK_BUILTIN_FUNCTION },
{ "BOOLEAN", TOK_BOOLEAN },
{ "BY", TOK_BY },
{ "CASE", TOK_CASE },
{ "CONST_E", TOK_E },
{ "CONSTANT", TOK_CONSTANT },
{ "CONTEXT", TOK_CONTEXT },
{ "COS", TOK_BUILTIN_FUNCTION },
{ "DERIVE", TOK_DERIVE },
{ "DIV", TOK_DIV },
{ "ELSE", TOK_ELSE },
{ "END", TOK_END },
{ "END_ALIAS", TOK_END_ALIAS },
{ "END_CASE", TOK_END_CASE },
{ "END_CONSTANT", TOK_END_CONSTANT },
{ "END_CONTEXT", TOK_END_CONTEXT },
{ "END_ENTITY", TOK_END_ENTITY },
{ "END_FUNCTION", TOK_END_FUNCTION },
{ "END_IF", TOK_END_IF },
{ "END_LOCAL", TOK_END_LOCAL },
{ "END_MODEL", TOK_END_MODEL },
{ "END_PROCEDURE", TOK_END_PROCEDURE },
{ "END_REPEAT", TOK_END_REPEAT },
{ "END_RULE", TOK_END_RULE },
{ "END_SCHEMA", TOK_END_SCHEMA },
{ "END_TYPE", TOK_END_TYPE },
{ "ENTITY", TOK_ENTITY },
{ "ENUMERATION", TOK_ENUMERATION },
{ "ESCAPE", TOK_ESCAPE },
{ "EXISTS", TOK_BUILTIN_FUNCTION },
{ "EXP", TOK_BUILTIN_FUNCTION },
{ "FALSE", TOK_LOGICAL_LITERAL },
{ "FIXED", TOK_FIXED },
{ "FOR", TOK_FOR },
{ "FORMAT", TOK_BUILTIN_FUNCTION },
{ "FROM", TOK_FROM },
{ "FUNCTION", TOK_FUNCTION },
{ "GENERIC", TOK_GENERIC },
{ "HIBOUND", TOK_BUILTIN_FUNCTION },
{ "HIINDEX", TOK_BUILTIN_FUNCTION },
{ "IF", TOK_IF },
{ "IN", TOK_IN },
{ "INCLUDE", TOK_INCLUDE },
{ "INSERT", TOK_BUILTIN_PROCEDURE },
{ "INTEGER", TOK_INTEGER },
{ "INVERSE", TOK_INVERSE },
{ "LENGTH", TOK_BUILTIN_FUNCTION },
{ "LIKE", TOK_LIKE },
{ "LIST", TOK_LIST },
{ "LOBOUND", TOK_BUILTIN_FUNCTION },
{ "LOCAL", TOK_LOCAL },
{ "LOG", TOK_BUILTIN_FUNCTION },
{ "LOG10", TOK_BUILTIN_FUNCTION },
{ "LOG2", TOK_BUILTIN_FUNCTION },
{ "LOGICAL", TOK_LOGICAL },
{ "LOINDEX", TOK_BUILTIN_FUNCTION },
{ "MOD", TOK_MOD },
{ "MODEL", TOK_MODEL },
{ "NOT", TOK_NOT },
{ "NUMBER", TOK_NUMBER },
{ "NVL", TOK_BUILTIN_FUNCTION },
{ "ODD", TOK_BUILTIN_FUNCTION },
{ "OF", TOK_OF },
{ "ONEOF", TOK_ONEOF },
{ "OPTIONAL", TOK_OPTIONAL },
{ "OR", TOK_OR },
{ "OTHERWISE", TOK_OTHERWISE },
{ "PI", TOK_PI },
{ "PROCEDURE", TOK_PROCEDURE },
{ "QUERY", TOK_QUERY },
{ "REAL", TOK_REAL },
{ "REFERENCE", TOK_REFERENCE },
{ "REMOVE", TOK_BUILTIN_PROCEDURE },
{ "REPEAT", TOK_REPEAT },
{ "RETURN", TOK_RETURN },
{ "ROLESOF", TOK_BUILTIN_FUNCTION },
{ "RULE", TOK_RULE },
{ "SCHEMA", TOK_SCHEMA },
{ "SELECT", TOK_SELECT },
{ "SELF", TOK_SELF },
{ "SET", TOK_SET },
{ "SIN", TOK_BUILTIN_FUNCTION },
{ "SIZEOF", TOK_BUILTIN_FUNCTION },
{ "SKIP", TOK_SKIP },
{ "SQRT", TOK_BUILTIN_FUNCTION },
{ "STRING", TOK_STRING },
{ "SUBTYPE", TOK_SUBTYPE },
{ "SUPERTYPE", TOK_SUPERTYPE },
{ "TAN", TOK_BUILTIN_FUNCTION },
{ "THEN", TOK_THEN },
{ "TO", TOK_TO },
{ "TRUE", TOK_LOGICAL_LITERAL },
{ "TYPE", TOK_TYPE },
{ "TYPEOF", TOK_BUILTIN_FUNCTION },
{ "UNIQUE", TOK_UNIQUE },
{ "UNKNOWN", TOK_LOGICAL_LITERAL },
{ "UNTIL", TOK_UNTIL },
{ "USE", TOK_USE },
{ "USEDIN", TOK_BUILTIN_FUNCTION },
{ "VALUE", TOK_BUILTIN_FUNCTION },
{ "VAR", TOK_VAR },
{ "WHERE", TOK_WHERE },
{ "WHILE", TOK_WHILE },
{ "XOR", TOK_XOR },
{ 0, 0}
};
int
SCANnextchar(char* buffer)
{
extern Boolean SCANread(void);
if (SCANtext_ready || SCANread()) {
buffer[0] = *(SCANcurrent++);
if (!isascii(buffer[0])) {
ERRORreport_with_line(ERROR_nonascii_char,yylineno,
0xff & buffer[0]);
buffer[0] = ' '; /* substitute space */
}
return 1;
} else
return 0;
}
static
void
SCANpush_buffer(char *filename,FILE *fp)
{
SCANbuffer.savedPos = SCANcurrent;
SCANbuffer.lineno = yylineno;
yylineno = 1;
++SCAN_current_buffer;
*(SCANcurrent = SCANbuffer.text) = '\0';
SCANbuffer.readEof = false;
SCANbuffer.file = fp;
SCANbuffer.filename = current_filename = filename;
}
static
void
SCANpop_buffer()
{
if (SCANbuffer.file != NULL)
fclose(SCANbuffer.file);
--SCAN_current_buffer;
SCANcurrent = SCANbuffer.savedPos;
yylineno = SCANbuffer.lineno; /* DEL */
current_filename = SCANbuffer.filename;
}
/*
** Requires: yyin has been set
*/
void
SCANinitialize(void)
{
struct keyword_entry *k;
keyword_dictionary = HASHcreate(100); /* not exact */
for (k=keywords;k->key;k++) {
DICTdefine(keyword_dictionary,k->key,(Generic)k,0,OBJ_UNKNOWN);
/* not "unknown", but certainly won't be looked up by type! */
}
#if 0
/* init macro table, destroy old one if any */
if (macros) HASHdestroy(macros);
macros = HASHcreate(16);
#endif
/* set up errors on first time through */
if (ERROR_include_file == ERROR_none) {
ERROR_include_file =
ERRORcreate("Could not open include file `%s'.", SEVERITY_ERROR);
ERROR_unmatched_close_comment =
ERRORcreate("unmatched close comment", SEVERITY_ERROR);
ERROR_unmatched_open_comment =
ERRORcreate("unmatched open comment", SEVERITY_ERROR);
ERROR_unterminated_string =
ERRORcreate("unterminated string literal", SEVERITY_ERROR);
ERROR_encoded_string_bad_digit = ERRORcreate(
"non-hex digit (%c) in encoded string literal", SEVERITY_ERROR);
ERROR_encoded_string_bad_count = ERRORcreate(
"number of digits (%d) in encoded string literal is not divisible by 8",SEVERITY_ERROR);
ERROR_bad_identifier = ERRORcreate(
"identifier (%s) cannot start with underscore",SEVERITY_ERROR);
ERROR_unexpected_character = ERRORcreate(
"character (%c) is not a valid lexical element by itself",SEVERITY_ERROR);
ERROR_nonascii_char = ERRORcreate(
"character (0x%x) is not in the EXPRESS character set",SEVERITY_ERROR);
}
}
int
SCANprocess_real_literal(void)
{
sscanf(exp_yytext, "%lf", &(exp_yylval.rVal));
return TOK_REAL_LITERAL;
}
int
SCANprocess_integer_literal(void)
{
sscanf(exp_yytext, "%d", &(exp_yylval.iVal));
return TOK_INTEGER_LITERAL;
}
int
SCANprocess_binary_literal(void)
{
exp_yylval.binary = SCANstrdup(exp_yytext+1); /* drop '%' prefix */
return TOK_BINARY_LITERAL;
}
int
SCANprocess_logical_literal(char * string)
{
switch (string[0]) {
case 'T': exp_yylval.logical = Ltrue; break;
case 'F': exp_yylval.logical = Lfalse; break;
default: exp_yylval.logical = Lunknown; break;
/* default will actually be triggered by 'UNKNOWN' keyword */
}
free(string);
return TOK_LOGICAL_LITERAL;
}
void
SCANlowerize(char *s)
{
for (;*s;s++) {
if (isupper(*s)) *s = tolower(*s);
}
}
void
SCANupperize(char *s)
{
for (;*s;s++) {
if (islower(*s)) *s = toupper(*s);
}
}
int
SCANprocess_identifier_or_keyword(void)
{
char *test_string;
struct keyword_entry *k;
int len;
char *src, *dest;
/* make uppercase copy */
len = strlen(exp_yytext);
dest = test_string = (char *)malloc(len+1);
for (src=exp_yytext;*src;src++,dest++) {
*dest = (islower(*src)?toupper(*src):*src);
}
*dest = '\0';
/* check for language keywords */
k = (struct keyword_entry *)DICTlookup(keyword_dictionary,test_string);
if (k) {
switch (k->token) {
case TOK_BUILTIN_FUNCTION:
case TOK_BUILTIN_PROCEDURE:
break;
case TOK_LOGICAL_LITERAL:
return SCANprocess_logical_literal(test_string);
default:
free(test_string);
return k->token;
}
}
/* now we have an identifier token */
#if 0
/* if macro invocation */
/* SCANpush_buffer(); */
/* strcpy(SCANbuffer.text, macro_expansion); */
/* return exp_yylex(); */
/* else */
element.key = test_string;
if ((found = HASHsearch(macros, &element, HASH_FIND)) != NULL) {
free(test_string);
SCANpush_buffer();
STRINGcopy_into(SCANbuffer.text, found->data);
return exp_yylex();
printf("\nexp_yylex = %s, scanbuffer.text=%s\n",exp_yylex(),SCANbuffer.text);
} else {
#endif
exp_yylval.symbol =SYMBOLcreate(test_string,yylineno,current_filename);
if (k) {
/* built-in function/procedure */
return(k->token);
} else {
/* plain identifier */
/* translate back to lower-case */
SCANlowerize(test_string);
return TOK_IDENTIFIER;
}
#if 0
return (k?k->token:TOK_IDENTIFIER);
#endif
#if 0
}
#endif
}
int
SCANprocess_string(void)
{
char *s, *d; /* source, destination */
/* strip off quotes */
exp_yylval.string = SCANstrdup(exp_yytext+1); /* remove 1st single quote */
s = strrchr(exp_yylval.string,'\'');
if (s) *s = '\0'; /* remove last single quote */
/* if string was unterminated, there will be no quote to remove */
/* in which case the scanner has already complained about it */
/* change pairs of quotes to single quotes */
for (s = d = exp_yylval.string;*s;) {
if (*s != '\'') {
*d++ = *s++;
} else if (0 == strncmp(s,"''",2)) {
*d++ = '\'';
s += 2;
}
}
*d = '\0';
return TOK_STRING_LITERAL;
}
int
SCANprocess_encoded_string(void)
{
char *s, *d; /* source, destination */
int count;
/* strip off quotes */
exp_yylval.string = SCANstrdup(exp_yytext+1); /* remove 1st double quote */
s = strrchr(exp_yylval.string,'"');
if (s) *s = '\0'; /* remove last double quote */
/* if string was unterminated, there will be no quote to remove */
/* in which case the scanner has already complained about it */
count = 0;
for (s = exp_yylval.string;*s;s++,count++) {
if (!isxdigit(*s)) {
ERRORreport_with_line(ERROR_encoded_string_bad_digit,yylineno,*s);
}
}
if (0 != (count%8)) {
ERRORreport_with_line(ERROR_encoded_string_bad_count,yylineno,count);
}
return TOK_STRING_LITERAL_ENCODED;
}
Boolean
SCANread(void)
{
int numRead;
Boolean done;
do {
/* this loop is guaranteed to terminate, since buffer[0] is on yyin */
while (SCANbuffer.file == NULL) {
SCANpop_buffer();
if (SCANtext_ready)
return true;
}
/* now we have a file buffer */
/* check for more stuff already buffered */
if (SCANtext_ready)
return true;
/* check whether we've seen eof on this file */
if (!SCANbuffer.readEof) {
numRead = fread(SCANbuffer.text,sizeof(char),SCAN_BUFFER_SIZE,SCANbuffer.file);
if (numRead < SCAN_BUFFER_SIZE) SCANbuffer.readEof = true;
#if 0
/* avoid read - nonportable */
SCANbuffer.readEof =
((numRead = read(fileno(SCANbuffer.file),
SCANbuffer.text,
SCAN_BUFFER_SIZE))
< SCAN_BUFFER_SIZE);
#endif
SCANbuffer.text[numRead] = '\0';
SCANcurrent = SCANbuffer.text;
}
if (!(done = SCANtext_ready)) {
if (SCAN_current_buffer == 0) {
done = true;
fclose(SCANbuffer.file); /* close yyin (I think) */
} else {
SCANpop_buffer();
}
}
} while (!done);
return SCANtext_ready;
}
#if macros_bit_the_dust
void
SCANdefine_macro(char * name, char * expansion)
{
Element element;
int len;
HMALLOC(element, Element, "hash table entry in SCANdefine_macro");
element->key = STRINGcopy(name);
len = STRINGlength(expansion);
STRALLOC(element->data, len + 1, "macro expansion in SCANdefine_macro");
STRINGcopy_into(element->data, expansion);
element->data[len] = '\n';
element->data[len + 1] = '\0';
HASHsearch(macros, element, HASH_INSERT);
}
#endif
void
SCANinclude_file(char *filename)
{
extern int print_objects_while_running;
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL) {
ERRORreport_with_line(ERROR_include_file, yylineno);
} else {
if (print_objects_while_running & OBJ_SCHEMA_BITS) {
fprintf(stderr,"parse: including %s at line %d of %s\n",
filename,yylineno,SCANbuffer.filename);
}
SCANpush_buffer(filename,fp);
}
}
char *
SCANstrdup(char *s)
{
char *s2 = (char *)malloc(strlen(s)+1);
if (!s2) return 0;
strcpy(s2,s);
return s2;
}