这是一个特定于解析解析器框架的问题,也是一般BNF/PEG的问题。
假设我有一个相当简单的正则表达式
^\\s*([A-Za-z_][A-Za-z_0-9]*)\\s*=\\s*(\\S+)\\s*$的伪EBNF。
<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半沸腾库的人来说,如何实现定义非空格的规则呢?
发布于 2011-03-04 03:14:24
在指定字符范围和对字符范围进行操作时,您只能使用词法生成器的约定。
许多词法分析器生成器接受十六进制值(类似于0x)来表示字符,因此您可以这样写:
'0'..'9'
0x30..\0x39用于数字。
对于非空格,您需要知道您使用的是哪个字符集。对于7位ASCII,非空白在概念上是所有打印字符:
0x21..\0x7E对于ISO8859-1:
( 0x21..\0x7E | 0x80-0xFF )您可以自己决定0x80以上的字符代码是否为空格(不间断的空格是否为空格?)您还可以决定控制字符0x0..0x1F的状态。制表符(0x9)是空格字符吗?CR 0xD和LF 0xA怎么样?ETB控制字符怎么样?
Unicode更难,因为它是一个庞大的集合,并且你的列表变得又大又乱。这就是生活。我们的DMS Software Reengineering Toolkit用于构建各种语言的解析器,并且必须支持ASCII、许多z的ISO8859-z和Unicode。DMS允许减法正则表达式,而不是编写复杂的“加法”正则表达式范围,因此我们可以这样写:
<UniCodeLegalCharacters>-<UniCodeWhiteSpace>这更容易理解,并且在第一次尝试时就会正确。
发布于 2013-10-04 17:51:59
在EBNF中,我会简单地将非空格定义为任何不是空格的字符:
nonwhitespace ::= anycharacter - whitespace这要求您有一个'anycharacter‘字面量来定义所有可能的符号,并明确定义哪些字符是空格。
在Parboiled中,您可以使用TestNot和ANY规则来完成此操作,例如,非空格将被定义为与WhiteSpace()规则不匹配的任何字符:
Sequence( TestNot(WhiteSpace()) , ANY )https://stackoverflow.com/questions/5184652
复制相似问题