当前位置: 首页 > 知识库问答 >
问题:

如何用ANTLR4解析XSD Regex的语法?

奚正谊
2023-03-14

亲爱的Antlr4社区,

grammar XSDRegExp;

regExp            :     branch ( '|' branch )* ;
branch            :     piece* ;
piece             :     atom quantifier? ;
quantifier        :     Quantifiers | '{'quantity'}' ;
quantity          :     quantRange | quantMin | QuantExact ;
quantRange        :     QuantExact ',' QuantExact ;
quantMin          :     QuantExact ',' ;
atom              :     NormalChar | '(' regExp ')' ;       // excluded | charClass  ;

QuantExact        :     [0-9]+ ;
NormalChar        :     ~[.\\?*+{}()|\[\]] ;        
Quantifiers       :     [?*+] ;     

解析似乎很顺利:

input    a(bd){6,7}c{14,15}

但是,我得到以下错误消息

input    12{3,4}

错误是:

[1]交换量子精确和正态分布的定义。但是交换在第一个输入中引入了一个错误:

line 1:6 no viable alternative at input '6'

因为在这种情况下,'6'只被视为一个正态分布,而不是一个全精确值。

[2]尝试为Quanteact(数量的花括号)创建一个上下文,这样lexer只在这个有限的上下文中提供Quanteact符号。但是我没有为此找到ANTLR4原语。

所以似乎什么都不起作用,因此我的问题是:我可以用ANTLR4解析这个语法吗?如果是,怎么做?

共有1个答案

米项禹
2023-03-14

我知道Lexer也可以将QuantExact作为第一个符号,但是由于解析器只查找NormalChar,所以我没有预料到会出现这个错误。

lexer不会“监听”解析器:无论解析器是否试图匹配normalchar,字符12都将始终匹配为quantacce。lexer试图匹配尽可能多的字符,如果出现平局,它将首先选择定义的规则。

您可以引入与normalcharquantacce匹配的normalchar规则,并在Atom中使用该规则:

atom              :     normalChar | '(' regExp ')' ;
normalChar        :     NormalChar | QuantExact ;

另一种选择是让lexer只创建单个char标记,并让解析器将这些标记粘合在一起(很像一个PEG)。类似于这样:

regExp            :     branch ( '|' branch )* ;
branch            :     piece* ;
piece             :     atom quantifier? ;
quantifier        :     Quantifiers | '{'quantity'}' ;
quantity          :     quantRange | quantMin | quantExact ;
quantRange        :     quantExact ',' quantExact ;
quantMin          :     quantExact ',' ;
atom              :     normalChar | '(' regExp ')' ; 
normalChar        :     NormalChar | Digit ;
quantExact        :     Digit+ ;

Digit             :     [0-9] ;
NormalChar        :     ~[.\\?*+{}()|\[\]] ;
Quantifiers       :     [?*+] ;
 类似资料:
  • 我对ANTLR相对来说是新的,所以请原谅我。 但是当我试图解析下面的表达式时 我最终出现以下错误: 第1:38行:'''处的令牌识别错误 第1:42行:'''处的令牌识别错误 规则r没有方法或者它有参数 规则'r'的意思是什么?我怎么能理解问题的原因呢?任何帮助都将不胜感激!

  • 我只剩下一个问题:我不知道如何处理RegEx文本的转角情况,如下所示: 被解释为RegEx文本,因为lexer规则始终处于活动状态。 我想要的是合并这个逻辑(C#代码。我需要JavaScript,但我不知道如何修改它):

  • 我一直在尝试使用antlr4为我需要的一个小型模板系统创建一个解析器。模板就像您看到的一些函数一样,总是以相同数量的{{和}}开始,并且在其中定义了将被pasd和执行的函数,并且应该用该函数结果替换整个内容。 问题是我想把函数之外的所有其他文本都放在一边,只解析我定义的内容。此时字符串不匹配或只保留其他文本。我想跳过或忽略除定义的函数之外的所有全文。 最终目标是用函数的结果替换整个{{...}}部

  • 作为我的小语言示例问题的延续,我想问一下如何解析下面的文本。这次只是想跳过尾巴规则,但它是一个岛,对我来说并不明显。最好的,不那么陈腐的方法? 使用以下使用词法模式的语法: 使用不同顺序的lexer规则。也尝试了更多的词汇命令,但没有成功。

  • 我所开发的ANTR4语法。在解析字符串期间 时间;25 10 * * *;' faccalc_minus1_cron.out.'yyyyMMdd。嗯;美国/New_York 我有以下错误 表达式中的字符无效!表达式:;'无效字符:;'无关输入“;”应为{“”,整数,“-”,“/”,“,”},缺少“;”“\uu”处的时区格式不正确:faccalc\u minus1 我不理解为什么,因为正则表达式规则

  • 我有一个语法,当解析在一次传递(整个文件)很好。 现在我希望将解析分解成组件。并在子库上运行解析器。我遇到了一个问题,我假设其他解析子库的人会看到下面的规则: 当上面的规则从一个顶级的开始规则解析到EOF时,一切都很好。当解析为子规则(而不是解析为EOF)时,解析器在没有thing子句时会感到不安,因为它希望看到“,”字符或EOF字符。 第8行:0不匹配的输入“%”应为{,“,”} 当我解析到EO