/* =========================================================== */
/* capaFormulaLexer.c created by Isaac Tsai @ Feb 1999 */
/* copyrighted by Isaac Tsai 1999 */
/* =========================================================== */
#include <ctype.h> /* isspace() */
#include <stdio.h> /* sscanf() */
#include "capaParser.h"
#include "capaFormula.h"
#include "capaToken.h"
/* --------------- Global variables ------------------------- */
extern int Func_idx;
extern Symbol FuncStack[MAX_FUNC_NEST];
extern char Fbuf[ONE_K]; /* lexer input buffer */
extern int Fidx; /* lexer input char index */
extern Symbol_p fml_lval; /* lexical variable used in parser */
/* ---- Token value returned from this lexer ---------------- */
/* --------------- Global variables ------------------------ */
/* scan a F_NUMBER token */
double
f_get_float()
{
double num;
int ii=0, len;
char num_str[QUARTER_K];
num_str[ii]=0;
while( isspace(Fbuf[Fidx]) ) { Fidx++; }
if( Fbuf[Fidx] == '+' || Fbuf[Fidx] == '-' ) {
num_str[ii++] = Fbuf[Fidx++];
}
while( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
num_str[ii++] = Fbuf[Fidx++];
}
if( Fbuf[Fidx] == 'E' || Fbuf[Fidx] == 'e' ) { /* a number followed immediately by e or E */
if( Fbuf[Fidx+1] == '+' || Fbuf[Fidx+1] == '-' || isdigit(Fbuf[Fidx+1]) ) {
/* e or E followed immediately by a digit */
num_str[ii++] = Fbuf[Fidx++];
num_str[ii++] = Fbuf[Fidx++];
while( isdigit(Fbuf[Fidx]) ) {
num_str[ii++] = Fbuf[Fidx++];
}
}
}
num_str[ii] = 0; /* terminate the str */
len = strlen(num_str);
if(len > 0 ) {
sscanf(num_str,"%lg", &num);
} else {
num = 1.0;
}
return (num);
}
char *
f_get_id()
{
char *var_p;
int ii=0, len;
char id_str[QUARTER_K];
id_str[ii]=0;
while( isspace(Fbuf[Fidx]) ) { Fidx++; }
if( isalpha( Fbuf[Fidx] ) ) {
id_str[ii++] = Fbuf[Fidx++];
}
while( isalnum(Fbuf[Fidx]) || Fbuf[Fidx] == '_' ) {
id_str[ii++] = Fbuf[Fidx++];
}
id_str[ii] = 0; /* terminate the str */
len = strlen(id_str);
var_p = (char *)capa_malloc( (len+1), sizeof(char));
strcpy(var_p,id_str);
return (var_p);
}
int
f_peek_next_token()
{
int idx;
idx = Fidx;
while( isspace(Fbuf[idx]) ) { idx++; }
return (Fbuf[idx]);
}
/* ======================================================= */
int
fml_lex()
{
char *id_p;
int c;
if( Fbuf[Fidx] == 0 ) { /* printf("EoI\n"); */ return (EOF); }
while( isspace(Fbuf[Fidx]) ) { Fidx++; }
if( isalpha(Fbuf[Fidx]) ) {
id_p = f_get_id();
c = f_peek_next_token();
if( c == '(' ) {
(FuncStack[Func_idx]).s_type = FUNCTION_ID;
(FuncStack[Func_idx]).s_name = id_p;
Func_idx++;
return (F_ID);
} else {
fml_lval = find_formula_id(id_p); capa_mfree((char *)id_p);
if( fml_lval == NULL) {
return (F_ERROR);
} else {
return (V_ID);
}
}
}
if( isdigit(Fbuf[Fidx]) || Fbuf[Fidx] == '.' ) {
fml_lval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
fml_lval->s_real = f_get_float();
fml_lval->s_type = R_CONSTANT;
return (F_NUMBER);
}
if( Fbuf[Fidx] == '(' ) {
Fidx++;
return (F_LPAR);
}
if( Fbuf[Fidx] == ')' ) {
Fidx++;
return (F_RPAR);
}
if( Fbuf[Fidx] == '+' ) {
Fidx++;
return (F_PLUS);
}
if( Fbuf[Fidx] == '-' ) {
Fidx++;
return (F_MINUS);
}
if( Fbuf[Fidx] == '*' ) {
Fidx++;
return (F_MULT);
}
if( Fbuf[Fidx] == '/' ) {
Fidx++;
return (F_DIV);
}
if( Fbuf[Fidx] == '%' ) {
Fidx++;
return (F_MOD);
}
if( Fbuf[Fidx] == '^' ) {
Fidx++;
return (F_POW);
}
if( Fbuf[Fidx] == ',' ) {
Fidx++;
return (F_COMMA);
}
return (F_ERROR);
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>