393 #define EXPRESSION_PARSER_STATICS 396 #define MAX_FUNC_ARG_LEN 255 404 var_store_ptr *stack;
405 var_store_ptr predefined_vars;
406 var_store_ptr named_vars;
407 var_store_ptr unnamed_vars;
409 const char *parse_str;
420 ParseError error_code;
424 void *(*trans_numeric) (
const char *digit_str,
425 gchar *radix_point, gchar *group_char,
char **rstr);
426 void *(*numeric_ops) (
char op_sym,
void *left_value,
void *right_value);
427 void *(*negate_numeric) (
void *value);
428 void (*free_numeric) (
void *numeric_value);
429 void *(*func_op)(
const char *fname,
int argc,
void **argv );
433 #include "finproto.h" 434 #include "fin_static_proto.h" 435 #include "fin_spl_protos.h" 438 #define ARG_TOKEN ':' 439 #define VAR_TOKEN 'V' 440 #define NUM_TOKEN 'I' 441 #define STR_TOKEN '"' 443 #define STACK_INIT 50 445 #define UNNAMED_VARS 100 449 static char allowed_operators[] =
"+-*/()=:";
452 init_parser (var_store_ptr predefined_vars,
455 void *trans_numeric (
const char *digit_str,
459 void *numeric_ops (
char op_sym,
462 void *negate_numeric (
void *value),
463 void free_numeric (
void *numeric_value),
464 void *func_op(
const char *fname,
465 int argc,
void **argv ))
469 pe->predefined_vars = predefined_vars;
471 pe->stack = g_new0 (var_store_ptr, STACK_INIT);
472 pe->stack_size = STACK_INIT;
474 pe->radix_point = radix_point;
475 pe->group_char = group_char;
477 pe->numeric_value = NULL;
479 pe->trans_numeric = trans_numeric;
480 pe->numeric_ops = numeric_ops;
481 pe->negate_numeric = negate_numeric;
482 pe->free_numeric = free_numeric;
483 pe->func_op = func_op;
489 exit_parser (parser_env_ptr pe)
491 var_store_ptr vars, bv;
496 for (vars = pe->named_vars; vars; vars = bv)
498 g_free (vars->variable_name);
499 vars->variable_name = NULL;
502 pe->free_numeric (vars->value);
509 pe->named_vars = NULL;
516 pe->token_tail = NULL;
518 if (pe->numeric_value)
519 pe->free_numeric (pe->numeric_value);
520 pe->numeric_value = NULL;
526 ParseError get_parse_error (parser_env_ptr pe)
529 return PARSER_NO_ERROR;
531 return pe->error_code;
535 var_store_ptr parser_get_vars (parser_env_ptr pe)
540 return pe->named_vars;
546 delete_var (
char *var_name, parser_env_ptr pe)
548 unsigned ret = FALSE;
549 var_store_ptr nv, tv;
554 for (nv = pe->named_vars, tv = NULL; nv; tv = nv, nv = nv->next_var)
556 if (strcmp (nv->variable_name, var_name) == 0)
559 tv->next_var = nv->next_var;
561 pe->named_vars = nv->next_var;
563 g_free (nv->variable_name);
564 nv->variable_name = NULL;
566 pe->free_numeric (nv->value);
584 parse_string (var_store_ptr value,
const char *
string, parser_env_ptr pe)
592 pe->unnamed_vars = unnamed_vars;
593 memset (unnamed_vars, 0, UNNAMED_VARS *
sizeof (
var_store));
595 pe->parse_str = string;
596 pe->error_code = PARSER_NO_ERROR;
599 pe->tokens = g_new0(
char, strlen (
string) + 1);
600 pe->token_tail = pe->tokens;
610 if (strcmp (pe->tokens,
"(I)") == 0)
617 pe->negate_numeric (val->value);
623 if (pe->Token == EOS)
625 if ((pe->stack_cnt) && (retv = pop (pe)))
629 pe->parse_str = NULL;
632 pe->error_code = STACK_UNDERFLOW;
636 pe->unnamed_vars = NULL;
638 return (
char *) pe->parse_str;
643 pop (parser_env_ptr pe)
648 val = pe->stack[--(pe->stack_cnt)];
652 pe->error_code = STACK_UNDERFLOW;
660 push (var_store_ptr push_value, parser_env_ptr pe)
662 if (pe->stack_cnt > pe->stack_size)
664 pe->stack_size += STACK_INIT;
665 pe->stack = g_realloc (pe->stack,
666 pe->stack_size * sizeof (var_store_ptr));
669 pe->stack[(pe->stack_cnt)++] = push_value;
678 get_named_var (parser_env_ptr pe)
680 var_store_ptr retp = NULL, bv;
682 for (retp = pe->predefined_vars, bv = NULL; retp; retp = retp->next_var)
683 if (strcmp (retp->variable_name, pe->name) == 0)
686 if (!retp && pe->named_vars)
687 for (retp = pe->named_vars; retp; bv = retp, retp = retp->next_var)
688 if (strcmp (retp->variable_name, pe->name) == 0)
695 pe->named_vars = retp;
698 retp->variable_name = g_strdup (pe->name);
699 retp->type = VST_NUMERIC;
701 pe->trans_numeric (
"0", pe->radix_point, pe->group_char, NULL);
709 get_unnamed_var (parser_env_ptr pe)
711 var_store_ptr retp = NULL;
714 for (cntr = 0; cntr < UNNAMED_VARS; cntr++)
715 if (pe->unnamed_vars[cntr].use_flag == UNUSED_VAR)
717 retp = &(pe->unnamed_vars[cntr]);
718 retp->variable_name = NULL;
719 retp->use_flag = USED_VAR;
720 retp->type = VST_NUMERIC;
723 pe->free_numeric (retp->value);
730 pe->error_code = PARSER_OUT_OF_MEMORY;
737 free_var (var_store_ptr value, parser_env_ptr pe)
743 if (value->variable_name != NULL)
746 value->use_flag = UNUSED_VAR;
750 pe->free_numeric (value->value);
756 add_token (parser_env_ptr pe,
char token)
759 if ((token != EOS) || (*pe->token_tail != EOS))
761 *pe->token_tail = token;
768 next_token (parser_env_ptr pe)
771 const char *str_parse = pe->parse_str;
774 while (isspace (*str_parse))
785 else if (strchr (allowed_operators, *str_parse))
787 add_token (pe, *str_parse++);
788 if (*str_parse == ASN_OP)
792 if (pe->Token != ASN_OP)
795 pe->asn_op = pe->Token;
796 add_token (pe, ASN_OP);
799 pe->error_code = UNDEFINED_CHARACTER;
803 else if ( *str_parse ==
'"' )
810 *nstr++ = *str_parse++;
812 while ( *str_parse !=
'"' );
815 add_token( pe, STR_TOKEN );
818 else if (isalpha (*str_parse)
819 || (*str_parse ==
'_'))
829 if ( *str_parse ==
'(' )
835 *nstr++ = *str_parse++;
837 while ((*str_parse ==
'_')
838 || (*str_parse ==
'(')
839 || isalpha (*str_parse)
840 || isdigit (*str_parse));
845 add_token(pe, FN_TOKEN);
849 add_token(pe, VAR_TOKEN);
854 else if ((number = pe->trans_numeric (str_parse, pe->radix_point,
855 pe->group_char, &nstr)))
857 add_token (pe, NUM_TOKEN);
858 pe->numeric_value = number;
864 add_token (pe, *str_parse);
865 pe->error_code = UNDEFINED_CHARACTER;
868 pe->parse_str = str_parse;
880 assignment_op (parser_env_ptr pe)
890 while (pe->Token == ASN_OP)
898 if (vl->variable_name)
921 vl->assign_flag = ASSIGNED_TO;
928 vl->value = pe->numeric_ops (ao, vl->value, vr->value);
929 pe->free_numeric (temp);
933 if (!vr->variable_name)
935 pe->free_numeric (vl->value);
936 vl->value = vr->value;
941 pe->numeric_ops (ASN_OP, vl->value, vr->value);
952 pe->error_code = NOT_A_VARIABLE;
961 add_sub_op (parser_env_ptr pe)
968 multiply_divide_op (pe);
972 while ((pe->Token == ADD_OP) || (pe->Token == SUB_OP))
987 multiply_divide_op (pe);
1001 rslt = get_unnamed_var (pe);
1009 rslt->value = pe->numeric_ops (op, vl->value, vr->value);
1021 multiply_divide_op (parser_env_ptr pe)
1032 while ((pe->Token == MUL_OP) || (pe->Token == DIV_OP))
1061 rslt = get_unnamed_var (pe);
1069 rslt->value = pe->numeric_ops (op, vl->value, vr->value);
1084 check_expression_grammar_error(parser_env_ptr pe)
1086 if (pe->Token == VAR_TOKEN
1087 || pe->Token == STR_TOKEN
1088 || pe->Token == NUM_TOKEN
1089 || pe->Token == FN_TOKEN)
1092 pe->error_code = EXPRESSION_ERROR;
1107 primary_exp (parser_env_ptr pe)
1109 var_store_ptr rslt = NULL;
1112 char LToken = pe->Token;
1120 ident = g_strdup( pe->name );
1135 if (pe->Token ==
')')
1147 add_token (pe, EOS);
1148 pe->error_code = UNBALANCED_PARENS;
1163 if (LToken == SUB_OP)
1164 pe->negate_numeric (rslt->value);
1169 rslt = get_unnamed_var (pe);
1173 if (check_expression_grammar_error(pe))
1176 rslt->value = pe->numeric_value;
1177 pe->numeric_value = NULL;
1183 if (pe->Token && pe->Token !=
')')
1188 if ( pe->error_code )
1191 if (!pe->Token || pe->Token ==
')')
1197 while (pe->Token != ARG_TOKEN);
1200 if ( pe->Token !=
')' )
1202 add_token( pe, EOS );
1203 pe->error_code = UNBALANCED_PARENS;
1211 argv = g_new0(
void*, funcArgCount );
1212 for ( i = 0; i < funcArgCount; i++ )
1218 argv[funcArgCount - i - 1] = val;
1221 rslt = get_unnamed_var(pe);
1222 rslt->value = (*pe->func_op)( ident, funcArgCount, argv );
1224 for ( i = 0; i < funcArgCount; i++ )
1226 free_var( argv[i], pe );
1231 if ( rslt->value == NULL )
1233 pe->error_code = NOT_A_FUNC;
1234 add_token( pe, EOS );
1241 if (check_expression_grammar_error(pe))
1247 if (check_expression_grammar_error(pe))
1250 rslt = get_named_var (pe);
1253 if (!(pe->Token ==
')' 1254 || pe->Token == ARG_TOKEN))
1257 pe->error_code = EXPRESSION_ERROR;
1261 rslt = get_unnamed_var( pe );
1262 rslt->type = VST_STRING;
1263 rslt->value = ident;