/// 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 }