17

我很难阐明 Chomsky 类型 2(上下文无关语言)和 Chomsky 类型 3(常规语言)之间的区别。

有人可以用简单的英语给我答案吗?我无法理解整个层次结构。

4

3 回答 3

25

II 型文法是带有堆栈的 III 型文法

II 型语法基本上是带有嵌套的 III 型语法。

III型语法(常规):

用例 - CSV(逗号分隔值)

特征:

  • 可以使用 FSM(有限状态机)读取
  • 不需要中间存储
  • 可以用正则表达式读取
  • 通常使用一维或二维数据结构表示
  • 是扁平的,意味着没有嵌套或递归属性

前任:

this,is,,"an "" example",\r\n
"of, a",type,"III\n",grammar\r\n

只要您能弄清楚上述文本的所有规则和边缘情况,您就可以解析 CSV。

II型语法(上下文无关):

用例 - HTML(超文本标记语言)或一般的 SGML

特征:

  • 可以使用 DPDA(确定性下推自动机)读取
  • 将需要一个堆栈用于中间存储
  • 可以表示为 AST(抽象语法树)
  • 可能包含嵌套和/或递归属性

HTML 可以表示为常规语法:

<h1>Useless Example</h1>
<p>Some stuff written here</p>
<p>Isn't this fun</p>

但它尝试使用 FSM 解析它:

<body>
  <div id=titlebar>
    <h1>XHTML 1.0</h1>
    <h2>W3C's failed attempt to enforce HTML as a context-free language</h2>
  </div>
  <p>Back when the web was still pretty boring, the W3C attempted to standardize away the quirkiness of HTML by introducing a strict specification</p
  <p>Unfortunately, everybody ignored it.</p>
</body>

看到不同?想象一下,您正在编写一个解析器,您可以从一个打开标签开始并在一个结束标签上结束,但是当您在到达结束标签之前遇到第二个开始标签时会发生什么?

很简单,您将第一个开始标签压入堆栈并开始解析第二个标签。对存在的尽可能多的嵌套级别重复此过程,如果语法结构良好,则可以在构建堆栈的相反级别一次展开堆栈

由于“纯”上下文无关语言的严格性质,它们相对较少,除非它们是由程序生成的。JSON,就是一个典型的例子。

上下文无关语言的好处是,虽然表达能力很强,但解析起来仍然相对简单。


但是等等,我不是说 HTML 是上下文无关的。是的,如果它是格式良好的(即 XHTML)。

虽然 XHTML 可能被认为是上下文无关的,但定义更宽松的 HTML 实际上会被认为是类型 I(即上下文敏感)。原因是,当解析器遇到结构不佳的代码时,它实际上会根据周围的上下文决定如何解释代码。例如,如果一个元素缺少结束标签,则需要先确定该元素在层次结构中的位置,然后才能决定应该放置结束标签的位置。

可以使上下文无关语言上下文敏感的其他功能包括模板、导入、预处理器、宏等。

简而言之,上下文相关语言看起来很像上下文无关语言,但上下文相关语言的元素可能会根据程序状态以不同的方式解释。

免责声明:我没有接受过 CompSci 的正式培训,因此此答案可能包含错误或假设。如果你问我终端和非终端之间的区别,你会得到一个空白的凝视。通过实际构建一个类型 III(常规)解析器并广泛阅读其余内容,我学到了很多东西。

于 2013-01-08T03:18:56.423 回答
6

维基百科页面有一个很好的图片和要点。

粗略地说,可以描述常规语言的底层机器不需要内存。它在输入上作为状态机 (DFA/NFA) 运行。正则语言也可以用正则表达式来表达。

一种具有“下一个”复杂程度的语言是一种上下文无关语言。描述这种语言的底层机器需要一些内存才能表示上下文无关且不规则的语言。请注意,向您的机器添加内存会使其功能更强大,因此它仍然可以表达开始时不需要内存的语言(例如常规语言)。底层机器通常是一个下推自动机

于 2012-07-18T20:15:49.430 回答
5

类型 3 语法由一系列状态组成。他们无法表达嵌入。例如,类型 3 语法不能要求匹配括号,因为它无法显示括号应该“包裹”其内容。这是因为,正如 Derek 指出的那样,Type 3 语法不会“记住”任何关于它通过到达当前状态的先前状态的任何内容。

类型 2 语法由一组“产生式”(您可以将它们视为模式)组成,其中可以嵌入其他产生式。因此,它们是递归定义的。一个产品只能根据它包含的内容来定义,而不能“看到”它之外的东西;这就是使语法与上下文无关的原因。

于 2012-07-18T20:27:11.843 回答