예제 #1
0
/// Decodes the syntax of an XPath expression. On entry, the lexical analysis has already
/// produced a list of basic tokens. 
/// \n Throws : syntax_error, syntax_overflow
void token_syntax_decoder::v_syntax_decode ()
{
   bool o_res;

   // group double tokens ('!=', '::', ...)
   v_tokenize_expression ();

   // reset list start
   v_set_current_top ();

   u_nb_recurs = 0;

   // the XPath expression, well, ..., must be an xpath_expr
   o_res = o_recognize (xpath_expr, true);
   if (! o_res)
      throw syntax_error ("main level");
   #ifdef DUMP_SYNTAX
      if (ltp_get (0))
         printf ("!!! Still to decode : %s !!!\n", cp_disp_class_lex (ltp_get (0) -> lex_get_value ()));
      else
         printf ("Completely parsed\n");
      printf ("%d recursions\n", u_nb_recurs);
   #endif
}
/// Decodes an XPath expression, further manipulating a token list
/// \n On input, we have a list of basic lexical tokens. We only merge here the 
/// multiple tokens : like '::' or '!='. We also delete whitespace tokens
void token_list::v_tokenize_expression ()
{
   v_set_current_top ();
   while (ltp_get (1))
   {
      switch (ltp_get (0) -> lex_get_value ())
      {
         case lex_colon :
            if (ltp_get (1) -> lex_get_value () == lex_colon)
            {
               v_replace_current (lex_2_colon, "::");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_slash :
            if (ltp_get (1) -> lex_get_value () == lex_slash)
            {
               v_replace_current (lex_2_slash, "//");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_exclam :
            if (ltp_get (1) -> lex_get_value () == lex_equal)
            {
               v_replace_current (lex_not_equal, "!=");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_lt :
            if (ltp_get (1) -> lex_get_value () == lex_equal)
            {
               v_replace_current (lex_lt_equal, "<=");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_gt :
            if (ltp_get (1) -> lex_get_value () == lex_equal)
            {
               v_replace_current (lex_gt_equal, ">=");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_dot :
            if (ltp_get (1) -> lex_get_value () == lex_dot)
            {
               v_replace_current (lex_2_dot, "..");
               v_delete_next ();
            }
            else
               v_inc_current (1);
            break;
         case lex_space :
            v_delete_current ();
            break;
         default :
            v_inc_current (1);
            break;
      }     // switch
   }     // while
}