如何根据一组 ABNF 语法规则对输入进行标记化

问题描述

我已阅读 the ABNF specification 上的 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]

还有一个 core rules 列表,我不会在这里发布描述预期的通用规则。

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

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 进行检查,以查看它是否匹配。有些规则比这更复杂,比如邮政编码的 5DIGIT ["-" 4DIGIT],但任何潜在的标记也需要根据此规则进行检查(“12345”和“12345-6789”都是有效的标记)。因此,似乎整个规则元素的连接也需要完全检查,除非“12345-6789”应该被标记为 ["12345","-","6789"] 这...可能是正确的?
  2. 我假设我们不想完全检查引用其他规则的规则,否则我们最终可能会将整个邮政地址标记为“邮政地址”类型的单个标记。也许不应该检查引用其他规则的规则?也许存在不包含规则引用(不包括核心规则)的“终端规则”之类的东西?
  3. 有时在规则中,终端值与规则引用相结合,例如在“personal-part”的定义中,文字“.”。被定义为。因此,虽然我们可能不想将任何潜在的标记字符串与整个“个人部分”规则定义相匹配,但似乎我们确实想尝试将其与文字“.”相匹配。因为它是解析个人部分所需的令牌。也许在非终端规则中,应该考虑列出的终端值?

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

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)