首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EBNF / parboiled:如何将regexp转换为PEG?

EBNF / parboiled:如何将regexp转换为PEG?
EN

Stack Overflow用户
提问于 2011-03-04 02:06:23
回答 2查看 1.1K关注 0票数 3

这是一个特定于解析解析器框架的问题,也是一般BNF/PEG的问题。

假设我有一个相当简单的正则表达式

代码语言:javascript
复制
^\\s*([A-Za-z_][A-Za-z_0-9]*)\\s*=\\s*(\\S+)\\s*$

的伪EBNF。

代码语言:javascript
复制
<line>               ::= <ws>? <identifier> <ws>? '=' <nonwhitespace> <ws>?
<ws>                 ::= (' ' | '\t' | {other whitespace characters})+
<identifier>         ::= <identifier-head> <identifier-tail>
<identifier-head>    ::= <letter> | '_'    
<identifier-tail>    ::= (<letter> | <digit> | '_')*
<letter>             ::= ('A'..'Z') | ('a'..'z')
<digit>              ::= '0'..'9'
<nonwhitespace>      ::= ___________

如何在EBNF中定义非空格(一个或多个不是空格的字符)?

对于熟悉Java半沸腾库的人来说,如何实现定义非空格的规则呢?

EN

回答 2

Stack Overflow用户

发布于 2011-03-04 03:14:24

在指定字符范围和对字符范围进行操作时,您只能使用词法生成器的约定。

许多词法分析器生成器接受十六进制值(类似于0x)来表示字符,因此您可以这样写:

代码语言:javascript
复制
 '0'..'9'
 0x30..\0x39

用于数字。

对于非空格,您需要知道您使用的是哪个字符集。对于7位ASCII,非空白在概念上是所有打印字符:

代码语言:javascript
复制
0x21..\0x7E

对于ISO8859-1:

代码语言:javascript
复制
( 0x21..\0x7E | 0x80-0xFF )

您可以自己决定0x80以上的字符代码是否为空格(不间断的空格是否为空格?)您还可以决定控制字符0x0..0x1F的状态。制表符(0x9)是空格字符吗?CR 0xD和LF 0xA怎么样?ETB控制字符怎么样?

Unicode更难,因为它是一个庞大的集合,并且你的列表变得又大又乱。这就是生活。我们的DMS Software Reengineering Toolkit用于构建各种语言的解析器,并且必须支持ASCII、许多z的ISO8859-z和Unicode。DMS允许减法正则表达式,而不是编写复杂的“加法”正则表达式范围,因此我们可以这样写:

代码语言:javascript
复制
 <UniCodeLegalCharacters>-<UniCodeWhiteSpace>

这更容易理解,并且在第一次尝试时就会正确。

票数 5
EN

Stack Overflow用户

发布于 2013-10-04 17:51:59

在EBNF中,我会简单地将非空格定义为任何不是空格的字符:

代码语言:javascript
复制
nonwhitespace ::= anycharacter - whitespace

这要求您有一个'anycharacter‘字面量来定义所有可能的符号,并明确定义哪些字符是空格。

在Parboiled中,您可以使用TestNotANY规则来完成此操作,例如,非空格将被定义为与WhiteSpace()规则不匹配的任何字符:

代码语言:javascript
复制
Sequence( TestNot(WhiteSpace()) , ANY )
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5184652

复制
相关文章

相似问题

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