Пример #1
0
END_TEST


START_TEST (test_FormulaTokenizer_empty)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_END );
  fail_unless( t->value.ch == '\0'   );
  Token_free(t);

  /**
   * Subsequent calls to FormulaTokenizer_nextToken() should continue to
   * return TT_END.
   */
  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_END );
  fail_unless( t->value.ch == '\0'   );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_END );
  fail_unless( t->value.ch == '\0'   );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #2
0
END_TEST


START_TEST (test_FormulaTokenizer_numbers_nan_inf)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("NaN Inf");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL       );
  fail_unless( t->value.real != t->value.real );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type                   == TT_REAL );
  fail_unless( util_isInf(t->value.real) == 1       );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #3
0
END_TEST


START_TEST (test_FormulaTokenizer_names)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("foobar Foo2Bar _Foo_Bar");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME               );
  fail_unless( !strcmp(t->value.name, "foobar") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME                );
  fail_unless( !strcmp(t->value.name, "Foo2Bar") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME                 );
  fail_unless( !strcmp(t->value.name, "_Foo_Bar") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #4
0
END_TEST

START_TEST (test_FormulaTokenizer_numbers_exp_bug)
{
  /* we were failing to correctly parse an exponentional followed 
  * by a sign with no space
  */
  const char         *formula = "12.3e1+.314E1";
  FormulaTokenizer_t *ft      = FormulaTokenizer_createFromFormula(formula);
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == 12.3      );
  fail_unless( t->exponent   == 1         );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_PLUS );
  fail_unless( t->value.ch == '+'     );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == .314      );
  fail_unless( t->exponent   == 1         );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #5
0
END_TEST


START_TEST (test_FormulaTokenizer_operators)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("+-*/^(),");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_PLUS );
  fail_unless( t->value.ch == '+'     );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_MINUS );
  fail_unless( t->value.ch == '-'      );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_TIMES );
  fail_unless( t->value.ch == '*'      );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_DIVIDE );
  fail_unless( t->value.ch == '/'       );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_POWER );
  fail_unless( t->value.ch == '^'      );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_LPAREN );
  fail_unless( t->value.ch == '('       );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_RPAREN );
  fail_unless( t->value.ch == ')'       );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_COMMA );
  fail_unless( t->value.ch == ','      );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless(t->type      == TT_END );
  fail_unless( t->value.ch == '\0'   );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #6
0
END_TEST


START_TEST (test_Token_free_NULL)
{
  Token_free(NULL);
}
Пример #7
0
END_TEST


START_TEST (test_Token_free)
{
  Token_t *t = Token_create();


  t->type       = TT_NAME;
  t->value.name = safe_strdup("foo");

  Token_free(t);
}
Пример #8
0
END_TEST


START_TEST (test_FormulaTokenizer_numbers_locale)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("2.72");
  Token_t            *t;


  setlocale(LC_NUMERIC, "de_DE");

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL );
  fail_unless( t->value.real == 2.72    );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  setlocale(LC_NUMERIC, "C");

  FormulaTokenizer_free(ft);
}
Пример #9
0
END_TEST


START_TEST (test_Token_create)
{
  Token_t *t = Token_create();


  fail_unless( t->type          == TT_UNKNOWN );
  fail_unless( t->value.ch      == '\0'       );
  fail_unless( t->value.name    == NULL       );
  fail_unless( t->value.integer == 0          );
  fail_unless( t->value.real    == 0.0        );
  fail_unless( t->exponent      == 0          );

  Token_free(t);
}
Пример #10
0
END_TEST


START_TEST (test_FormulaTokenizer_whitespace)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula(" \t \n ");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);

  fail_unless( t->type     == TT_END );
  fail_unless( t->value.ch == '\0'   );

  Token_free(t);
  FormulaTokenizer_free(ft);
}
Пример #11
0
END_TEST


START_TEST (test_FormulaTokenizer_unknown)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("*****@*****.**");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME                   );
  fail_unless( !strcmp(t->value.name, "bbornstein") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_UNKNOWN );
  fail_unless( t->value.ch == '@'        );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME            );
  fail_unless( !strcmp(t->value.name, "acm") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type     == TT_UNKNOWN );
  fail_unless( t->value.ch == '.'        );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_NAME            );
  fail_unless( !strcmp(t->value.name, "org") );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #12
0
END_TEST


START_TEST (test_FormulaTokenizer_numbers)
{
  FormulaTokenizer_t *ft = FormulaTokenizer_createFromFormula("123 3.14 .007 6.7 5.");
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type          == TT_INTEGER );
  fail_unless( t->value.integer == 123        );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL );
  fail_unless( t->value.real == 3.14    );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL );
  fail_unless( t->value.real == .007    );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL );
  fail_unless( t->value.real == 6.7     );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL );
  fail_unless( t->value.real == 5.0     );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
CK_CPPSTART
#endif

/**
 * The following are private and used only within FormulaParser.c; however,
 * I don't know how else to make them "public" only for testing than to put
 * them here
 */
#define START_STATE   0
#define ACCEPT_STATE  0
#define ERROR_STATE  27
#define NUM_STATES   27


/**
 * The Action[] table contains 144 entries.  To test them all would be
 * laborious and silly.  Instead, for a few token type, test the first,
 * last and middle entry in each token "run".  Also, test some error
 * states.
 */
START_TEST (test_FormulaParser_getAction)
{
  int i;
  Token_t *t = Token_create();


  t->type = TT_NAME;
  fail_unless( FormulaParser_getAction( 0, t) == 6, NULL );
  fail_unless( FormulaParser_getAction(10, t) == 6, NULL );
  fail_unless( FormulaParser_getAction(25, t) == 6, NULL );
  fail_unless( FormulaParser_getAction( 1, t) == ERROR_STATE, NULL );

  t->type = TT_INTEGER;
  fail_unless( FormulaParser_getAction( 0, t) == 1, NULL );
  fail_unless( FormulaParser_getAction(10, t) == 1, NULL );
  fail_unless( FormulaParser_getAction(25, t) == 1, NULL );
  fail_unless( FormulaParser_getAction( 1, t) == ERROR_STATE, NULL );

  t->type = TT_PLUS;
  fail_unless( FormulaParser_getAction( 1, t) ==  -9, NULL );
  fail_unless( FormulaParser_getAction(16, t) ==  -2, NULL );
  fail_unless( FormulaParser_getAction(24, t) == -11, NULL );
  fail_unless( FormulaParser_getAction( 2, t) == ERROR_STATE, NULL );

  t->type = TT_MINUS;
  fail_unless( FormulaParser_getAction( 0, t) ==  5, NULL );
  fail_unless( FormulaParser_getAction(16, t) == -2, NULL );
  fail_unless( FormulaParser_getAction(25, t) ==  5, NULL );
  fail_unless( FormulaParser_getAction( 2, t) == ERROR_STATE, NULL );

  t->type = TT_END;
  fail_unless( FormulaParser_getAction( 1, t) ==  -9, NULL );
  fail_unless( FormulaParser_getAction(17, t) ==  -5, NULL );
  fail_unless( FormulaParser_getAction(24, t) == -11, NULL );
  fail_unless( FormulaParser_getAction( 3, t) == ERROR_STATE, NULL );


  /**
   * TT_UNKNOWN should always yield an error state.
   */
  t->type = TT_UNKNOWN;
  for (i = 0; i < NUM_STATES; i++)
  {
    fail_unless( FormulaParser_getAction(i, t) == ERROR_STATE, NULL );
  }

  Token_free(t);
}
Пример #14
0
END_TEST


START_TEST (test_FormulaTokenizer_numbers_exp)
{
  const char         *formula = "12.3e1 .314E1 7e-3 .067e2 5E0 2e+12 3e 4";
  FormulaTokenizer_t *ft      = FormulaTokenizer_createFromFormula(formula);
  Token_t            *t;


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == 12.3      );
  fail_unless( t->exponent   == 1         );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == .314      );
  fail_unless( t->exponent   == 1         );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real ==  7        );
  fail_unless( t->exponent   == -3        );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == .067      );
  fail_unless( t->exponent   == 2         );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == 5.0       );
  fail_unless( t->exponent   == 0         );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == 2         );
  fail_unless( t->exponent   == 12        );
  Token_free(t);

  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type       == TT_REAL_E );
  fail_unless( t->value.real == 3.0       );
  fail_unless( t->exponent   == 0         );
  Token_free(t);

  /**
   * Gobble-up the '4'.  This last token is here as a test to ensure the
   * previous token is not interpreted as 3e4.
   */
  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type          == TT_INTEGER );
  fail_unless( t->value.integer == 4          );
  Token_free(t);


  t = FormulaTokenizer_nextToken(ft);
  fail_unless( t->type == TT_END );
  Token_free(t);

  FormulaTokenizer_free(ft);
}
Пример #15
0
/**
 * @if conly
 * @memberof ASTNode_t
 * @endif
 */
LIBSBML_EXTERN
ASTNode_t *
SBML_parseFormula (const char *formula)
{
  long rule, state, action;

  ASTNode_t *node = NULL;

  FormulaTokenizer_t *tokenizer = NULL; 
  Stack_t            *stack     = NULL;
  Token_t            *token     = NULL;

  if (formula == NULL) return NULL;
  
  tokenizer = FormulaTokenizer_createFromFormula(formula);
  token     = FormulaTokenizer_nextToken(tokenizer);
  stack     = Stack_create(20);


  Stack_push(stack, (void *) START_STATE);

  while (1)
  {
    state  = (long) Stack_peek(stack);
    action = FormulaParser_getAction(state, token);

    if (action == ACCEPT_STATE)
    {
      node = Stack_peekAt(stack, 1);
      break;
    }

    else if (action == ERROR_STATE)
    {
      /**
       * Free ASTNodes on the Stack, skip the states.
       */
      while (Stack_size(stack) > 1)
      {
        Stack_pop(stack);
        ASTNode_free( Stack_pop(stack) );
      }

      node = NULL;
      break;
    }

    /**
     * Shift
     */
    else if (action > 0)
    {
      Stack_push( stack, ASTNode_createFromToken(token) );
      Stack_push( stack, (void *) action );

      Token_free(token);
      token = FormulaTokenizer_nextToken(tokenizer);
    }

    /**
     * Reduce
     */
    else if (action < 0)
    {
      rule  = -action;
      node  = FormulaParser_reduceStackByRule(stack, rule);
      state = (long) Stack_peek(stack);

      Stack_push( stack, node );
      Stack_push( stack, (void *) FormulaParser_getGoto(state, rule) );
    }
  }

  FormulaTokenizer_free(tokenizer);
  Stack_free(stack);
  Token_free(token);

  return node;
}