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)
615 pe->negate_numeric (val->value);
620 if (pe->Token == EOS)
622 if ((pe->stack_cnt) && (retv = pop (pe)))
626 pe->parse_str = NULL;
629 pe->error_code = STACK_UNDERFLOW;
633 pe->unnamed_vars = NULL;
635 return (
char *) pe->parse_str;
640 pop (parser_env_ptr pe)
645 val = pe->stack[--(pe->stack_cnt)];
649 pe->error_code = STACK_UNDERFLOW;
657 push (var_store_ptr push_value, parser_env_ptr pe)
659 if (pe->stack_cnt > pe->stack_size)
661 pe->stack_size += STACK_INIT;
662 pe->stack = g_realloc (pe->stack,
663 pe->stack_size * sizeof (var_store_ptr));
666 pe->stack[(pe->stack_cnt)++] = push_value;
675 get_named_var (parser_env_ptr pe)
677 var_store_ptr retp = NULL, bv;
679 for (retp = pe->predefined_vars, bv = NULL; retp; retp = retp->next_var)
680 if (strcmp (retp->variable_name, pe->name) == 0)
683 if (!retp && pe->named_vars)
684 for (retp = pe->named_vars; retp; bv = retp, retp = retp->next_var)
685 if (strcmp (retp->variable_name, pe->name) == 0)
692 pe->named_vars = retp;
695 retp->variable_name = g_strdup (pe->name);
696 retp->type = VST_NUMERIC;
698 pe->trans_numeric (
"0", pe->radix_point, pe->group_char, NULL);
706 get_unnamed_var (parser_env_ptr pe)
708 var_store_ptr retp = NULL;
711 for (cntr = 0; cntr < UNNAMED_VARS; cntr++)
712 if (pe->unnamed_vars[cntr].use_flag == UNUSED_VAR)
714 retp = &(pe->unnamed_vars[cntr]);
715 retp->variable_name = NULL;
716 retp->use_flag = USED_VAR;
717 retp->type = VST_NUMERIC;
720 pe->free_numeric (retp->value);
727 pe->error_code = PARSER_OUT_OF_MEMORY;
734 free_var (var_store_ptr value, parser_env_ptr pe)
740 if (value->variable_name != NULL)
743 value->use_flag = UNUSED_VAR;
747 pe->free_numeric (value->value);
753 add_token (parser_env_ptr pe,
char token)
756 if ((token != EOS) || (*pe->token_tail != EOS))
758 *pe->token_tail = token;
765 next_token (parser_env_ptr pe)
768 const char *str_parse = pe->parse_str;
771 while (isspace (*str_parse))
782 else if (strchr (allowed_operators, *str_parse))
784 add_token (pe, *str_parse++);
785 if (*str_parse == ASN_OP)
789 if (pe->Token != ASN_OP)
792 pe->asn_op = pe->Token;
793 add_token (pe, ASN_OP);
796 pe->error_code = UNDEFINED_CHARACTER;
800 else if ( *str_parse ==
'"' )
807 *nstr++ = *str_parse++;
809 while ( *str_parse !=
'"' );
812 add_token( pe, STR_TOKEN );
815 else if (isalpha (*str_parse)
816 || (*str_parse ==
'_'))
826 if ( *str_parse ==
'(' )
832 *nstr++ = *str_parse++;
834 while ((*str_parse ==
'_')
835 || (*str_parse ==
'(')
836 || isalpha (*str_parse)
837 || isdigit (*str_parse));
842 add_token(pe, FN_TOKEN);
846 add_token(pe, VAR_TOKEN);
851 else if ((number = pe->trans_numeric (str_parse, pe->radix_point,
852 pe->group_char, &nstr)))
854 add_token (pe, NUM_TOKEN);
855 pe->numeric_value = number;
861 add_token (pe, *str_parse);
862 pe->error_code = UNDEFINED_CHARACTER;
865 pe->parse_str = str_parse;
877 assignment_op (parser_env_ptr pe)
887 while (pe->Token == ASN_OP)
895 if (vl->variable_name)
918 vl->assign_flag = ASSIGNED_TO;
925 vl->value = pe->numeric_ops (ao, vl->value, vr->value);
926 pe->free_numeric (temp);
930 if (!vr->variable_name)
932 pe->free_numeric (vl->value);
933 vl->value = vr->value;
938 pe->numeric_ops (ASN_OP, vl->value, vr->value);
949 pe->error_code = NOT_A_VARIABLE;
958 add_sub_op (parser_env_ptr pe)
965 multiply_divide_op (pe);
969 while ((pe->Token == ADD_OP) || (pe->Token == SUB_OP))
984 multiply_divide_op (pe);
998 rslt = get_unnamed_var (pe);
1006 rslt->value = pe->numeric_ops (op, vl->value, vr->value);
1018 multiply_divide_op (parser_env_ptr pe)
1029 while ((pe->Token == MUL_OP) || (pe->Token == DIV_OP))
1058 rslt = get_unnamed_var (pe);
1066 rslt->value = pe->numeric_ops (op, vl->value, vr->value);
1081 check_expression_grammar_error(parser_env_ptr pe)
1083 if (pe->Token == VAR_TOKEN
1084 || pe->Token == STR_TOKEN
1085 || pe->Token == NUM_TOKEN
1086 || pe->Token == FN_TOKEN)
1089 pe->error_code = EXPRESSION_ERROR;
1104 primary_exp (parser_env_ptr pe)
1106 var_store_ptr rslt = NULL;
1109 char LToken = pe->Token;
1117 ident = g_strdup( pe->name );
1132 if (pe->Token ==
')')
1144 add_token (pe, EOS);
1145 pe->error_code = UNBALANCED_PARENS;
1160 if (LToken == SUB_OP)
1161 pe->negate_numeric (rslt->value);
1166 rslt = get_unnamed_var (pe);
1170 if (check_expression_grammar_error(pe))
1173 rslt->value = pe->numeric_value;
1174 pe->numeric_value = NULL;
1180 if (pe->Token && pe->Token !=
')')
1185 if ( pe->error_code )
1188 if (!pe->Token || pe->Token ==
')')
1194 while (pe->Token != ARG_TOKEN);
1197 if ( pe->Token !=
')' )
1199 add_token( pe, EOS );
1200 pe->error_code = UNBALANCED_PARENS;
1208 argv = g_new0(
void*, funcArgCount );
1209 for ( i = 0; i < funcArgCount; i++ )
1215 argv[funcArgCount - i - 1] = val;
1218 rslt = get_unnamed_var(pe);
1219 rslt->value = (*pe->func_op)( ident, funcArgCount, argv );
1221 for ( i = 0; i < funcArgCount; i++ )
1223 free_var( argv[i], pe );
1228 if ( rslt->value == NULL )
1230 pe->error_code = NOT_A_FUNC;
1231 add_token( pe, EOS );
1238 if (check_expression_grammar_error(pe))
1244 if (check_expression_grammar_error(pe))
1247 rslt = get_named_var (pe);
1250 if (!(pe->Token ==
')' 1251 || pe->Token == ARG_TOKEN))
1254 pe->error_code = EXPRESSION_ERROR;
1258 rslt = get_unnamed_var( pe );
1259 rslt->type = VST_STRING;
1260 rslt->value = ident;