ABNF的Unicode版本?

ABNF的Unicode版本?,unicode,grammar,abnf,Unicode,Grammar,Abnf,我想为一种文件格式编写语法,其内容可以包含US-ASCII以外的字符。因为我习惯了ABNF,所以我试着用它 但是,没有一个RFC和一个对不使用我们ASCII的人非常友好 事实上,我正在寻找一个ABNF版本(可能还有一些基本规则),它是面向字符的,而不是面向字节的;关于这一点,RFC 5234唯一要说的是第2.4节: 2.4. External Encodings External representations of terminal value characters will var

我想为一种文件格式编写语法,其内容可以包含US-ASCII以外的字符。因为我习惯了ABNF,所以我试着用它

但是,没有一个RFC和一个对不使用我们ASCII的人非常友好

事实上,我正在寻找一个ABNF版本(可能还有一些基本规则),它是面向字符的,而不是面向字节的;关于这一点,RFC 5234唯一要说的是第2.4节:

2.4.  External Encodings

   External representations of terminal value characters will vary
   according to constraints in the storage or transmission environment.
   Hence, the same ABNF-based grammar may have multiple external
   encodings, such as one for a 7-bit US-ASCII environment, another for
   a binary octet environment, and still a different one when 16-bit
   Unicode is used.  Encoding details are beyond the scope of ABNF,
   although Appendix B provides definitions for a 7-bit US-ASCII
   environment as has been common to much of the Internet.

   By separating external encoding from the syntax, it is intended that
   alternate encoding environments can be used for the same syntax.
这并不能真正澄清问题


是否有一个ABNF版本是面向代码点而不是面向字节的?

如果您正在编写的ABNF是供人阅读的,那么我会说只使用普通语法,并引用代码点而不是字节。您可以查看允许在源文本中使用Unicode的各种语言规范,例如C#、Java、PowerShell等。它们都有语法,并且都必须在某个地方定义Unicode字符(例如标识符)

例如,PowerShell语法有如下行:

双引号字符:
U+0022

左双引号(
U+201C

右双引号(
U+201D

双低-9引号(
U+201E

或者在Java规范中:

Unicode输入字符:
UnicodeScape
输入字符

UnicodeScape:
\
UnideMarker六位数字六位数字六位数字六位数字

Unicodermarker:
u

UnicodeMarker
u

RawInputCharacter:
任何Unicode字符

六位数:其中一个
01123456789abcdefabcdef

这里的
\
u
和十六进制数字都是ASCII字符

请注意,周围有解释意图的文本——这总比把一堆语法丢给某人要好

如果是为了自动生成语法分析器,您最好找到一个工具,该工具允许您以Unicode和ABNF格式指定语法,并将其发布。不过,编写语法分析器的人应该了解这两种格式。

请参阅,其中说明:

规则解析为一个终端值字符串,有时称为 在ABNF中,字符仅仅是一个非负整数。 在某些上下文中,将值映射(编码)到 将指定字符集(如ASCII)


Unicode只是一组非负整数U+0000到U+10FFFF减去代理范围D800-DFFF,有各种RFC相应地使用ABNF。例如。

我确实编写了解析器(我是grappa的维护者);但如果已经定义了一种好的语法语言,我不想再发明另一种语法语言,除非它对i18n不友好!在这种情况下,我会说只使用普通ABNF,并明确指出,在为终端指定字符数据时,您使用的是Unicode码点,而不是ASCII值。但这使得指定终端变得困难对于整个Unicode字符类来说……相当麻烦。这在某种程度上可能不是官方的,但人们应该能够理解它。我刚刚写的一个例子:
未替换的普通字符=%x00-5B/%x7C/%x7E-D7FF/%xE000-10FFFF
。只是别忘了同情那些将阅读它的可怜的人,并添加这样的注释:
;除了“\”、“{”和“}”
之外的任何Unicode代码点(并检查以确保您排除的范围事实上也是正确的!)嘿,我刚刚来到这里,去写一条注释来更正之前的注释,但却注意到我是编写该注释的人!好吧,更正是注释应该是可读的“任意Unicode标量值”,而不是“任意Unicode代码点”;U+D800–U+DFFF是有效的Unicode代码点,但不是有效的Unicode标量值,除非您正在处理UTF-16的威胁并通过代码点访问它(避免这样做!),否则您关心的是标量值。