0

我已阅读有关ABNF 规范的 RFC,并且很难理解如何使用一组 ABNF 规则从与语法匹配的某些输入字符串中可靠地提取标记。似乎该规范从未提及令牌或 AST,因此它可能不关心这一点,但我相信这将是应用任何 BNF 语法的最终目标,除非我弄错了。

在规范中,他们列出了解析邮政地址的示例规则:

postal-address   = name-part street zip-part

name-part        = *(personal-part SP) last-name [SP suffix] CRLF
name-part        =/ personal-part CRLF

personal-part    = first-name / (initial ".")
first-name       = *ALPHA
initial          = ALPHA
last-name        = *ALPHA
suffix           = ("Jr." / "Sr." / 1*("I" / "V" / "X"))

street           = [apt SP] house-num SP street-name CRLF
apt              = 1*4DIGIT
house-num        = 1*8(DIGIT / ALPHA)
street-name      = 1*VCHAR

zip-part         = town-name "," SP state 1*2SP zip-code CRLF
town-name        = 1*(ALPHA / SP)
state            = 2ALPHA
zip-code         = 5DIGIT ["-" 4DIGIT]

还有一个核心规则列表,我不会在此处发布描述预期的常用规则。

最终,我想做的是找出接受输入所需的规则

John H. Doe
12345 Fakestreet
Springfield, IL 55555

并生成我认为正确的令牌序列,即:

[ "John", " ", "H", ".", "Doe", "\r\n", "12345", " ", "Fakestreet", "\r\n", "Springfield", ",", " ", "IL", " ", "55555", "\r\n"] (我认为空格和 CRLF 需要作为“令牌”返回,因为它们在某些规则中被指定为要求)

我正在考虑的一些问题:

  1. “Fakestreet”应该是它自己的标记是有道理的,但根据定义,它是可见字符核心规则的可变重复。理想情况下,我不想将每个字母作为其自己的标记(“F”、“a”、“k”等)读出,因此(假设核心规则可以被视为终端?)任何潜在的标记字符串都会需要对照整个理论上无限的规则定义1*VCHAR来检查它是否匹配。有些规则比这更复杂,比如 zip-code's 5DIGIT ["-" 4DIGIT],但是任何潜在的标记也需要根据这个规则进行检查(“12345”和“12345-6789”都是有效的标记)。所以似乎整个规则元素连接也需要完全检查,除非“12345-6789”"12345""-", "6789"] 哪个...可能是正确的?
  2. 我假设我们不想完全检查引用其他规则的规则,否则我们最终可能会将整个邮政地址标记为“邮政地址”类型的单个标记。也许不应该检查引用其他规则的规则?也许有诸如“终端规则”之类的东西,它不包括规则参考(不包括核心规则)?
  3. 偶尔在规则中,终端值与规则引用结合,例如在“personal-part”的定义中,即文字“.”。被定义为。因此,虽然我们可能不想将任何潜在的标记字符串与整个“个人部分”规则定义进行匹配,但似乎我们确实想尝试将其与文字“.”进行匹配。因为它是解析个人部分所需的令牌。也许在非终端规则中,应该考虑列出的终端值?

我意识到这是一个冗长的问题,但似乎 EBNF 和 ABNF 之类的 BNF 超集正在用于此类事情,但我找不到如何从 ABNF 语法进行标记的标准规范。

4

0 回答 0