ANTLR:在任何字符序列前面检测可选标记

ANTLR:在任何字符序列前面检测可选标记,antlr,Antlr,目标是匹配URL(不含协议),其中可能包含也可能不包含可选主机名。比如说 amce.com/a/path /另一个/path/expr a/路径/非/以/斜杠开始 所有3个都应该匹配,但理想情况下,语法允许在第一个表达式中恢复主机名acme.com 因此,解析器语法在理想情况下如下所示: url: hostname? pathExpr 问题出在词法语法上 比如说 fragment ALPHANUM: [a-zA-Z0-9-]; fragment NAME: ALPHANUM+; HOST

目标是匹配URL(不含协议),其中可能包含也可能不包含可选主机名。比如说

  • amce.com/a/path
  • /另一个/path/expr
  • a/路径/非/以/斜杠开始
所有3个都应该匹配,但理想情况下,语法允许在第一个表达式中恢复主机名acme.com

因此,解析器语法在理想情况下如下所示:

url: hostname? pathExpr
问题出在词法语法上

比如说

fragment ALPHANUM: [a-zA-Z0-9-];
fragment NAME: ALPHANUM+;

HOSTNAME: NAME ( '.' NAME)+ -> mode (PATH_MODE);

mode PATH_MODE;
PATH_EXPR: .+;
对于第一种情况可以正常工作,但与其他2种情况不匹配

我该怎么做


(注意:对于默认模式,我尝试用任意路径表示规则,定义一个不以主机名开头的字符序列,但失败了)

我建议不要在这里重复使用。有一个,它应该给你所有你想要的细节

更新:

为了使整个主机/端口部分成为可选部分,您只需修改url规则如下:

url
   : authority '://' login? host (':' port)? ('/' path)? ('?' search)?
   | '/'? path ('?' search)?
;

你已经试过了吗?我也看到这种语法不是很灵活。路径部分之前的几乎每个部分都是可选的(如权限、登录信息、端口等)。

谢谢。我已经尝试过破解它,但我无法让它匹配没有主机名的URI(删除方案要求不是问题)。