繁体   English   中英

在 C 编程语言的上下文中,什么是产生式?

[英]What is a production in the context of the C Programming language?

在 Kernighan 和 Ritchie 编写的 The C Programming Language, Second Edition 的附录 A 中,提到了产生这个词:

本手册描述了由 1988 年 10 月 31 日提交给 ANSI 的草案指定的 C 语言,该草案被批准为“美国信息系统标准 - 编程语言 C,X3.159-1989”。该手册是对提议的解释标准,而不是标准本身,尽管已经注意使其成为该语言的可靠指南。 在大多数情况下,本文档遵循标准的大致大纲,而后者又遵循本书第一版的大纲,尽管组织结构有所不同。 除了重命名一些产生式,并且没有形式化词法标记或预处理器的定义外,这里给出的语言本身的语法与标准的语法是等价的。

但是,我似乎无法弄清楚它的实际含义。 我的猜测是它指的是语法部分中键的值:

翻译单元:外部声明翻译单元外部声明

A 13 节中的以下部分应该暗示作者的意思,但我似乎无法自己弄清楚,因为我错过了一些基本术语:

该文法具有未定义的终结符号整数常量、字符常量、浮点常量、标识符、字符串和枚举常量; 打字机风格的单词和符号是字面上给出的终端 该语法可以机械地转换为自动解析器生成器可接受的输入。 除了添加用于指示产生式中的替代项的任何句法标记外,有必要扩展“one of”结构,并且(取决于解析器生成器的规则)使用 opt 符号复制每个产生式,一次使用符号和一次没有。 通过进一步的更改,即删除产生式 typedef-name: identifier 并使 typedef-name 成为终端符号,该语法对于 YACC 解析器生成器是可以接受的。 它只有一个冲突,由 if-else 歧义产生。

我也不知道那些大胆的词/句子是什么意思。 有人可以给我一个见解吗?

在计算机科学中,形式语法是使用产生式规则来描述的。 例如,以下形式的规则:

P → xyz

表示符号P可以被符号 xyz 替换,并且形式的规则

Q → 一个P |

表示符号Q可以由符号 a 和符号P或由符号 b 和符号P代替。

形式语法指定一个开始符号,例如Q ,并说明哪些符号是非终结符号(未出现在最终字符串中的占位符),哪些是终结符号(可能出现在最终字符串中)。 如果Q是具有上述两个规则的文法的开始符号,那么这些规则描述了一个包含两个字符串 axyz 和 bxyz 的文法,因为它们是唯一可以使用这些规则生成的两个字符串。 语法可以产生的字符串集合称为它的语言。

λ 常用来表示一个空字符串,一个没有符号的字符串。

该文法具有非终结符号S 、终结符号 a 和 b 以及起始符号S

S → a S bb | λ

可以通过将S替换为空字符串来生成空字符串,或者可以通过将S替换为S bb 然后用空字符串替换新的S来生成 abb,或者可以通过将S替换为S bb 然后替换来生成 aabbbb新的S带有一个S bb,产生 aa S bbbb,然后用空字符串替换S ,产生 aabbbb。 我们可以看到这个语法的语言是所有字符串的集合,其中包含一定数量的 a 字符(可能为零),后跟两倍的 b 字符。

C 标准使用形式语法定义 C 语言(有一些限定和英语修改)。 例如,它包含这个产生式(它使用“:”而不是我上面使用的“→”,并使用单独的行而不是“|”来表示选择):

声明
标记语句
复合语句
表达式语句
选择陈述
迭代语句
跳转语句

关于您以粗体标记的其他术语:

未定义的终端符号整数常量,…

appears to be a partial grammar, leaving integer-constant as an undefined symbol, and hence acting as a terminal symbol. The 中给出的 C 文法似乎是部分文法,将integer-constant作为未定义的符号,因此充当终端符号。 在官方 ANSI C 1990 标准中,它是官方 ANSI C 1990 标准中定义的非终结符。

…打字机风格的单词和符号是字面上给出的终端。

这在原版中更加清晰,其中使用的字体表明“打字机”样式是固定宽度的字体:

typewriter风格的单词和符号是字面上给出的终端。

这及其前面的文本意味着,在语法中,斜体单词,如声明,是语法的非终结符号,通过语法的产生“成为其他东西”,而“打字机”字体中的单词,像typedef一样,是终端符号,它们是名称中文字字符的符号; 语法中的typedef表示源代码中的字符 t、y、p、e、d、e 和 f。

……用 opt 符号复制每个产品,一次有符号,一次没有……

该标准使用下标“opt”,如下所示:

P : Q R选择

表示R是可选的。 形式上,这实际上是两条规则:

PQ R
PQ

意思是有一条规则用Q R代替P和一条用Q代替P的规则,两者都可以使用。 因此, R是可选的。 使用“opt”下标只是编写规则的另一种方式。

… 这个语法对于 YACC 解析器生成器是可以接受的。 它只有一个冲突,由 if-else 歧义产生。

在计算机科学理论中,解析器是检查字符串是否属于某种语言的软件。 (在实践中,它经常同时做其他有用的事情,比如通过将字符串的一部分解释为数字、部分解释为变量等来为字符串分配“含义”。) YACC 是读取语法规范的软件并为语法描述的语言的解析器生成源代码。

YACC 生成的解析器类型需要决定在读取每个令牌时将应用哪个产品。 当语法不足以确定要应用哪个产生式时,就会发生冲突。 在 C 形式文法中, if (x) if (y) S1 else S2可以通过两种方式产生,一种将else S2与第一个if相关联,另一种将else S2与第二个if相关联。 这必须通过在语法中添加信息来解决; if当前没有else ,则 YACC 被告知将else S2与最近的 S2 相关联。

“符号”是语法的一个元素。

例如在你引用的部分:

翻译单元
外部声明翻译单元外部声明

这四个都是象征。

“产品”解释了符号的组成。 您的报价是一个单一的产品,它指出一个翻译单元按顺序由三件事组成: external-declaration ,然后是 translation-unit ,然后是 external-declaration


“终端”符号是在其定义中没有任何其他符号的符号。

例如,您的translation-unit不是终端,但这个是:

数字:其中之一
0 1 2 3 4 5 6 7 8 9

如果单个数字是终端,或者整个“数字”是终端,那就没有实际意义了; 可能是前者。

这些也是“字面上给出的”,这意味着数字实际上是在标准中拼写的。

这是一个没有按字面意思给出的终端:

基本 c 字符
翻译字符集的任何成员,除了 U+0027 撇号、U+005c 反斜线或换行符

注意他们没有拼出所有可能的字符,因为它们太多了,而是提供了纯文本描述。


“未定义”终端只是未解释/定义的终端,使得语法在技术上不完整。 如果他们称“integer-constant”为未定义终端,则意味着他们的语法未能包含integer-constant: blah blah


使用 opt 符号复制每个产品,一次使用该符号,一次不使用

考虑:


x选择y

这里fooxxy

他们建议用另一种方法来拼写相同的东西,而不使用“opt”:


y
x y


它只有一个冲突,由 if-else 歧义产生。

解析程序是通过从单个符号开始,并找出哪些产生式将其转换为您要解析的文本来完成的。

如果有不止一个生产序列可以做到这一点,则语法是“模棱两可的”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM