首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有贪婪通配符和转义字符的ANTLR中的字符串词法规则

具有贪婪通配符和转义字符的ANTLR中的字符串词法规则
EN

Stack Overflow用户
提问于 2019-02-22 02:46:28
回答 1查看 198关注 0票数 1

来自“最后的反the 4参考”一书:

我们的字符串规则还不够好,因为它不允许字符串中的双引号。为了支持这一点,大多数语言都定义以反斜杠开头的转义序列。为了在双引号字符串中获得双引号,我们使用\"。为了支持常见的转义字符,我们需要以下内容:

代码语言:javascript
复制
STRING ​: ​ ​'"' ​( ESC |.)*?​ ​'"' ​ ​;
fragment
ESC ​: ​ ​'\\"'  | ​ ​'\\\\' ​ ​; ​ ​// 2-char sequences \" and \\ 

反斜杠本身需要转义转义字符,所以我们需要\\来指定反斜杠字符。字符串中的循环现在通过调用片段规则ESC来匹配转义字符序列,或者通过点通配符匹配任何单个字符。*?子规则运算符终止(ESC |.)*?

这听起来不错,但当我读到在ESC.之间的选择时,我注意到了一定的模糊性。就STRING而言,可以通过将转义字符\.匹配来匹配输入\,并将以下转义双引号视为结束字符串。这将更不贪婪,因此更符合?的使用。

当然,问题是,如果我们这样做,那么我们有一个额外的双引号在结尾没有得到匹配的任何东西。

所以我写了以下语法:

代码语言:javascript
复制
grammar String;

anything: STRING '"'? '\r\n';

STRING: '"' (ESC|.)*? '"';
fragment
ESC: '\\"' | '\\\\';

它在字符串后面接受一个可选的孤独双引号字符。这个语法仍然将"Orange\""解析为一个完整字符串:

所以我的问题是:为什么这是被接受的解析,而不是以"Orange\"作为STRING的解析,然后是一个孤立的双引号"?请注意,后者不那么贪婪,这似乎更符合?的使用,因此人们可能会认为这样做更好。

EN

回答 1

Stack Overflow用户

发布于 2019-02-22 02:46:28

经过更多的实验后,我意识到选择运算符|是顺序相关的(但仅在非贪婪运算符?下):ESC是在.之前尝试的。如果我将两者倒置并编写(.|ESC)*?,我就会得到

这并不令人惊讶,但也是一个有趣的提醒,即ANTLR并不像我们有时所期望的那样具有声明性(在逻辑上--或者是顺序无关,但|不是)。这也很好地提醒我们,非贪婪操作符?并没有将其最小化功能扩展到所有选项,而只是扩展到与输入匹配的第一个选项(@sepp2k补充说,订单依赖只适用于非贪婪的情况)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54819338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档