HTML是一种无上下文语言吗?

51

阅读一些相关的问题使我思考了HTML的理论性质。

我指的不是类似XHTML的代码。我说的是这种疯狂的标记语言,它是完全有效的 HTML (!)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html<head>
<title//
<p ltr<span id=p></span</p>
</>

鉴于SGML在这里注入的巨大复杂性,HTML是否是一种无上下文语言?它是否仍然是一种形式语言?有一个文法吗?

那HTML5呢?

我对形式语言的概念还很陌生,请多包容。是的,我已阅读过维基百科文章 ;)


3
HTML不是上下文无关的,因为有效的HTML代码需要满足一些上下文条件,而这些条件不能由上下文无关文法规范处理(例如唯一的“id”属性等)。 - Nikos M.
4个回答

61

无上下文是语言理论中的一个概念,在解析器实现中具有重要意义。一个无上下文语言可以由一个无上下文文法描述,其中所有规则在箭头左侧只有一个非终止符号:

X→δ

这个简单的限制允许{{X}}在左侧出现的规则的右侧替换为它,而不考虑前面或后面出现了什么。例如,如果在推导或解析时到达以下位置:

αXλ 

有一件事是确定的

αδλ

这也是有效的。非上下文无关规则的例子包括:

XY→δ
Xa→δ
aX→δ

这些需要知道围绕着X可以推导出什么,才能确定规则是否适用,这会导致不确定性(围绕X的内容也想知道它推导出了什么),在解析中是不可行的,而且我们希望语言具有明确定义。

证明一种语言是上下文无关的唯一方法是证明存在一个上下文无关文法,这并不是一项容易的任务。大多数编程语言已经被描述为上下文无关文法,因此工作已经完成。但是还有其他语言,包括编程语言,使用逻辑或纯英语来描述,因此需要努力找出它们是否是上下文无关的。

对于HTML,关于它的上下文无关性的答案是肯定的。SGML是一个明确定义的上下文无关语言,定义在其之上的HTML也是一个上下文无关语言。这两种语言的解析器和文法在网络上广泛存在。无论如何,存在LL(k)文法可以证明HTML是上下文无关的,因为LL是上下文无关的一个已经证明的子集。

但是随着Web的发展,HTML强制浏览器将其视为不那么明确定义的。现代Web浏览器会尽力尝试从几乎任何它们发现的东西中渲染出合理的内容。它们使用的文法不是上下文无关文法,解析器比SGML/HTML所需的更为复杂。

HTML在多个层面上定义。

  1. 在词汇层面上,有关于有效字符、标识符、字符串等的规则。
  2. 下一层是XML,它由开放和关闭的<tags>组成,定义了一个分层文档结构。您可以将XML或类似XML的东西用于任何目的,就像 Apache Ant用于构建脚本一样。
  3. 接下来是HTML中有效的标签以及哪些标签可以嵌套在哪些标签内的规则。
  4. 接下来是关于哪些属性适用于哪些标签,以及可以嵌入HTML的语言(如CSS和JavaScript)的规则。
  5. 最后,您需要了解给定HTML文档的含义的语义规则。

句法部分定义得足够好,可以被verified。语义部分比句法部分大得多,它是根据浏览器对HTTP和Document Object Model(DOM)的操作及如何呈现模型到屏幕的方式进行定义的。

最终:

  1. 解析正确的HTML非常容易(它是无上下文和LL/LR的)。
  2. 解析实际存在于Web上的HTML很困难。
  3. 在HTML/CSS/DOM上实现语义(浏览器)非常困难。

1
一个明确定义的解析树是无歧义语法的产物,无论它是CFG还是其他类型。无歧义意味着如果一个序列是该语言的一部分,则存在唯一的解析树。请参见“规则”部分的编辑。 - Apalala
3
我不确定你列表中的第二项是否完全正确。有效的XHTML始终是有效的XML,但有效的HTML可能无法成为有效的XML。你是指SGML/DTD吗?其中一个巨大的区别是,在有效的HTML中可以省略/暗示结束标签(这是SGML所允许的),但在XML中无法省略/暗示结束标签。 - Merlyn Morgan-Graham
这个答案被踩了(引用自之前的评论),HTML不是上下文无关的,因为有效的HTML代码需要一些CFG规范无法处理的条件(例如唯一的id属性等),另请参见相关问题 - Nikos M.
2
@Apalala,查看链接的ANTLR文件表明HTML的无上下文状态取决于存在一组有限的有效HTML标签(例如<a><ul>等)。这是正确的吗?我是否正确地认为任意XML(例如<foo></foo>)是上下文相关的?关闭标记的名称需要与打开标记的名称匹配,而您不知道该名称是什么。 - Benjamin Hodgson
2
@Benjamin 的确。从正式意义上讲,如果标签事先不知道,那么就不能有严格的无上下文语法用于 XML。然而,如果我们假设匹配的闭合标签在语义层面上,则 XML 可以被 CFG 解析。请注意,像 Pascal 这样的语言可以使用 LL(1) 语法进行解析,该语法不会尝试检查标识符是否预先声明并使用适合其类型的运算符。实际使用的大多数解析器在解析时都会进行一些语义检查,以便尽早检测到明显的错误。 - Apalala
显示剩余10条评论

14

有效的HTML不是一种无上下文语言。

首先,HTML作为SGML的应用在实际中是虚构的,因此分析SGML来回答问题是无用的。(然而,SGML虚构可能也不是无上下文的。)

更有用的是看实际定义的HTML解析算法。它分为两个层次:标记化和树建立。HTML所谓的标记化操作比解析器通常所说的标记化操作更高级。在HTML的情况下,标记化将字符流分成像开始标签、结束标签、注释和文本这样的单元。标记生成器会扩展字符引用。通常,在讨论解析器时,你可能会将小于号之类的东西视为“标记”,并认为字符引用由标记组成而不是由标记生成器解决。

如果考虑将输入流拆分为标记的过程,那么HTML语言的这个层次是正则的(除了来自树构建器的反馈)。

然而,有三个问题需要解决:第一个问题是将输入流分成标记仅仅是开始,接下来就是树构建器的一面实际上关心标记中的标识符。第二个问题是树构建器反馈到标记器,因此标记器进行的一些状态转换取决于树构建器的状态!第三个问题是,语言中的有效文档由适用于树构建器阶段输出的规则定义,并且这些规则足够复杂,无法使用树自动机完全定义(如 RELAX NG 无法表达所有有效性约束所示)。
这不是一个实际的证明,但您可能可以通过从第2和第3个问题的复杂性中工作来开发真正的证明。
请注意,无效文档的情况并不特别有趣,因为问题不在于语言是否上下文无关,而是是否存在上下文无关文法,可生成所有可能的字符串,而不考虑解析树在HTML解析器中具有某种可理解的解释。 HTML解析器将成功消耗所有可能的字符串,因此从这个意义上说,所有可能的字符串都属于“无效HTML”语言。
编辑:留给读者的有趣问题:没有解析错误但忽略有效性的HTML是否是上下文无关语言?

如果HTML没有解析错误,只使用有效的元素名称而忽略一般有效性,那么它是否是一种无上下文语言?

(复杂情况#2适用于两种情况。)


3
你使用的“上下文无关语言”定义是哪个? - Apalala
1
@Apalala,一个简单的例子证明了HTML不是上下文无关的事实是html的id属性必须是唯一的,这不能由任何CFG描述,但它是HTML规范的一部分。请参阅相关问题 - Nikos M.
9
id 这样的东西应该由语义检查器处理,而不是解析器。如果你走这条路线,基本上所有静态类型的语言都不是上下文无关的,因为你需要对代码进行类型检查。 - semicolon
1
@分号 是的,基本上所有静态类型语言都是上下文敏感的。 - Miles Rout
2
好的程序如果没有类型检查通常被认为是语法上有效的。敏感空格是一个公正的观点,但即使在处理过程中未检测到类型错误,我仍然会称其为一种无上下文语言。 - semicolon
显示剩余3条评论

10

不是

请参见下面的编辑说明。

这要看情况。

如果您只考虑理论上的HTML子集,那么是的

但是,如果您还包括实际生活中可访问和成功使用的HTML,这些HTML每天在互联网上的许多顶级站点上被数百万人使用,那么不是

这就是HTML灵活性的来源。解析引擎会添加标记、关闭标记并处理一些理论上的CFG无法完成的任务。如果您学过自动机,可能会记得正式语法中的产生式规则不能为空(也称为epsilon/lambda)在lhs(左侧)。由于解析引擎基本上使用了正式语法和自动机没有的知识,因此它不受限于此,而“语法”将具有epsilon/lambda -> result,其中特定的epsilon/lambda规则是根据语法中不可用的信息选择的。

由于我认为任何正式语法都不允许空的lhs,因此HTML无法通过正式语法定义,根本不是正式语言。

当然,HTML5可能会尝试朝着“更正式”的语言描述方向发展,但它成为上下文无关语言的现实可能性(即未被语法匹配的字符串被拒绝)与XHTML 2.0席卷全球并取代HTML的可能性相同(XHTML是他们试图使HTML成为正式语言的尝试...由于其脆弱性而被大规模拒绝)。

值得注意的是,HTML 5是第一个在实现之前定义的HTML标准!没错,HTML 1-4由某人在浏览器中实现的随机想法组成,并根据受欢迎和广泛实现的功能制定标准。然后他们尝试了XHTML,但它完全未被采用。即使是在网上,“xhtml”在几乎所有情况下都会自动解析为HTML,以防止出现加密的语法错误而导致的问题。现在您可以看到我们是如何到达这里以及为什么不太可能很快正式化。

教训:“从理论上讲,理论和实践没有区别。实际上,有。” - 约吉·贝拉

编辑:

实际上,在阅读文件后,发现即使按照HTML 4.01规范,HTML也不符合SGML。要自行查看,请查看http://www.w3.org/TR/html4/strict.dtd处的HTML 4.01 Strict文档类型定义(doctype),并注意以下行:

HTML 4.01规范包括无法在DTD中表达的其他语法约束。

因此,我会说由于这些特性,它可能不是CFL(上下文无关语言),尽管它在技术上并没有证明存在一些可能接受HTML 4.01的PDA,但它确实阻止了SGML是CFL因此HTML是CFL的论点。

HTML5摒弃了对SGML的隐含一致性,但可能可以通过CFG进行描述。然而,它仍将提供基于最佳尝试的解析,而不是基于CFG的解析。因此,在这方面,目前的情况(即语言规范在形式上被定义,无效的字符串仍然被接受、解析和以最佳方式呈现)不太可能在很长时间内发生重大变化。请注意保留""和""和html标签。

我不知道你在分析中使用哪个无上下文语言的定义。DTD无法表达所有HTML的意思与原始问题无关。 - Apalala
2
@Apalala 这与原始问题有很大关系。Brandon正在提出一个观点(你显然不同意),即HTML不是SGML的子集,因此它没有相同的语法。更重要的是,他的观点是HTML“标准”(5之前)实际上是一种进化混乱,因此并没有真正定义清楚。而DTD与语言的形式定义密切相关,这使得你的评论难以理解。 - shovavnik
3
@shovavnik,请查看此查询中得票最高的答案。特别是,存在用于“正确”HTML的LL/LR解析器足以证明该语言按照定义是上下文无关的。Web的发展要求HTML解析器/渲染器深入探究人工智能来完成它们的工作,这很棒,但与原始问题无关。 - Apalala
说 HTML 不是 CFG,因为人们无法编写有效的 HTML,并不是一个证明。我并不是说我们不需要考虑这一点。只是 HTML 是 CFG,但如果我们需要实现一个浏览器/解释器,则需要实现许多智能错误处理。 - kam

5

HTML5与之前的HTML版本不同,它严格定义了代码解析行为,即使代码不完全正确。而早期的HTML解析器各不相同,每个解析器都会尽力“猜测”代码作者的意图。


2
当然可以,但在语法/语言理论的背景下,这意味着什么? - user123444555621
这意味着实际上它不是上下文无关的。 - Brandon
那么你的意思是因为人们不擅长编写有效的HTML,所以HTML不是CFG? - kam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接