无上下文语法识别行尾空白

时间:2014-09-13 17:21:35

标签: parsing context-free-grammar

我正在尝试编写一个无上下文语法来做一些非常简单的事情 - 将字符串解析为(1)行尾空白和(2)其他所有内容的交替部分列表。例如:

This.first.line...\n..and.this....second.line\n.\n..and.final.line

(将" "显示为".",将新行显示为"\n"以提高可读性)将被解析为

"This.first.line", "...\n..", "and.this....second.line", "\n.\n..", "and.final.line"

我写了这个语法:

string = raw_start | newline_start
raw_start = raw_section [newline_start]
newline_start = newline_section [raw_start]
raw_section = {any_character_except_newline}
newline_section = {whitespace_except_newline} new_line {any_whitespace_character}

但这不正确,因为{any_character_except_newline}会消耗导致换行符的空格,当我想要new_line_section中包含的空格时。{​​/ p>

是否有可能说"消费空间,除非它们在换行前是正确的"不会失去语法的无上下文属性?

2 个答案:

答案 0 :(得分:3)

当然,没有上下文不是问题。两个"行尾空白"和其他一切"是常规语言。

作为参考,这里是正则表达式(正式常规,而不是"可以通过一些' regex'包"识别)。我们假设 A 是字母表,并定义:

NOTSPACE = { ∀x | x ∈ A ∧ x ≠ NL ∧ x ≠ SPACE }
NOTEOL   = { ∀x | x ∈ A ∧ x ≠ NL }
EVERYTHING_ELSE = { xωy | x,y ∈ NOTSPACE ∧ ω ∈ NOTEOL* } ⋃ NOTSPACE
EOL_WHITESPACE = { ωNLγ | ω,γ ∈ {SPACE, NL}* }

这很容易转化为CFG。 (文本可能以空格结尾,但不包含换行符。以下忽略了这种可能性,但可以轻松添加):

S → Spaces
S → S Other
S → S EOL_WS
Spaces → ε
Spaces → Spaces [ ]
Other → [^ \n] Line [^ \n]
Other → [^ \n]
Line → ε
Line → Line [^\n]
EOL_WS → Spaces NL_Spaces
NL_Spaces → NL_Space
NL_Spaces → NL_Spaces NL_Space
NL_Space → [/n] Spaces
 

如上所述,上述内容含糊不清,因为它并不坚持OtherEOL_WS最长。这很容易修复但很乏味,而且由于OP只要求CFG而不是明确的或LR(1)CFG,我会留下它。

答案 1 :(得分:0)

这是我在我的问题中使用的EBNF格式的完美答案的翻译:

string = raw_start | newline_start
raw_start = raw_section [newline_start]
newline_start = newline_section [raw_start]
raw_section = any_nonwhite_character [{any_character_except_newline} any_nonwhite_character]
newline_section = {whitespace_except_newline} new_line {any_whitespace_character}

关键是改变raw_section的定义,要求它以非白色字符结尾。这个简单的语法不会匹配以空格结尾的空字符串或字符串,但这很容易修复。