【问题标题】:Failed to convert URL parser regular expression to Ragel无法将 URL 解析器正则表达式转换为 Ragel
【发布时间】:2012-01-09 07:01:07
【问题描述】:

我在 RFC 2396 和 RFC 3986 中找到了一个 URL 解析器正则表达式。

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

我将它转换为 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"

怎么了?

【问题讨论】:

  • 问题似乎出在“权限”部分,如果我删除它可以找到路径。现在,为什么权威部分不起作用......

标签: regex uri ragel


【解决方案1】:

你用错了监护人&lt;:,一旦权限部分看到你的第一个/,控制权交给了权限部分。

如果你看到&lt;: 的别名就很清楚了

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

这意味着,在与左侧表达式匹配的每个转换状态上,它将保持 HIGHER 优先级,避免右侧表达式。

如果你将 ABNF 符号转换为 ragel 会容易得多。

【讨论】:

    【解决方案2】:

    我最近自己也做了同样的事情,你可以看看我的 ragel 语法https://github.com/maximecaron/ragel-url-parser

    【讨论】:

      猜你喜欢
      • 2021-12-02
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 2010-11-06
      • 2011-03-20
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多