Не удалось преобразовать регулярное выражение анализатора URL в Ragel - PullRequest
2 голосов
/ 09 января 2012

Я нашел регулярное выражение анализатора URL в RFC 2396 и RFC 3986.

^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?

Я преобразовал его в Ragel:

%%{    
  # RFC 3986 URI Generic Syntax (January 2005)
  machine url_parser;

  action pchar     {
    printf("%c", fc);
  }
  action scheme            { printf("scheme\n"); }
  action scheme_end        { printf("\nscheme_end\n"); }
  action authority         { printf("authority\n"); }
  action authority_end     { printf("\nauthority_end\n"); }
  action path              { printf("path\n"); }
  action path_end          { printf("\npath_end\n"); }
  action query             { printf("query\n"); }
  action query_end         { printf("\nquery_end\n"); }
  action fragment          { printf("fragment\n"); }
  action fragment_end      { printf("\nfragment_end\n"); }

  scheme    = (any - [:/?#])+ >scheme    $pchar %scheme_end ;
  authority = (any - [/?#])*  >authority $pchar %authority_end ;
  path      = (any - [?#])*   >path      $pchar %path_end ;
  query     = (any - [#])*    >query     $pchar %query_end ;
  fragment  = (any)*          >fragment  $pchar %fragment_end ; 
  main     := (( scheme ":" )?) <: (( "//" authority )?) <: path ( "?" query )? ( "#" fragment )?;
}%%

#include <cstdio>
#include <cstdlib>
#include <string>

/** Data **/
%% write data;

int main(int argc, char **argv) {
  std::string str(argv[1]);
  char const* p = str.c_str();
  char const* pe = p + str.size();
  char const* eof = pe;
  int cs = 0;

  %% write init;
  %% write exec;

  return p - str.c_str();
}

Это работает, когда я вводю абсолютный URI.

liangxu@dev64:~$ ./uri_test "http://www.ics.uci.edu/pub/ietf/uri/?c=www&rot=1&e=%20%20"
scheme
http
scheme_end
authority
www.ics.uci.edu
authority_end
path
/pub/ietf/uri/
path_end
query
c=www&rot=1&e=%20%20
query_end

И успех при вводе полномочий и пути:

liangxu@dev64:~$ ./uri_test "//www.ics.uci.edu/pub/ietf/uri/?c=www&rot=1&e=%20%20"
authority
www.ics.uci.edu
authority_end
path
/pub/ietf/uri/
path_end
query
c=www&rot=1&e=%20%20
query_end

Но сбой при вводе только пути:

liangxu@dev64:~$ ./uri_test "/pub/ietf/uri"

Что не так?

Ответы [ 2 ]

0 голосов
/ 08 апреля 2014

Я сам недавно сделал то же самое, вы можете взглянуть на мою грамматику ragel https://github.com/maximecaron/ragel-url-parser

0 голосов
/ 25 апреля 2013

U используете неправильного опекуна <:, как только раздел полномочий увидит ваш первый /, контроль передается разделу полномочий.

Это ясно, если вы видите псевдоним <:, который

expr $(unique_name,1) . expr >(unique_name,0)

Это означает, что при каждом переходном состоянии, которое соответствует левому выражению, оно будет иметь приоритет HIGHER, избегая правильного выражения.

Намного проще, если вы конвертируете нотацию ABNF в ragel.

...