yacc语法树系列(二)

350 阅读4分钟

这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战

本文为译文,原文链接:dinosaur.compilertools.net/yacc/

1:基本规范

命名适用于tokens和非终止符号。yacc要求命名被声明成这样。另外,基于第三章讨论的原因,通常包含词法分析器作为规范文件的一部分是可取的;并且包含其他程序可能也是有用的。因此,每个规范文件由三个部分组成:声明,语法规则,和程序。这些部分被用两个百分号"%%"分隔开来标记。(百分号”%“通常被用在yacc规范里面作为一种逃逸字符)

也就是说,一个完整的规范文件长这样

        declarations
        %%
        rules
        %%
        programs

声明(declarations)部分可能是空的。此外,如果程序(programs)部分被省略了,第二个%%可能也被省略掉;

因此,最小的合法yacc规范是:

%%
rules

空白页,退格和新行会被忽略掉,除非这些不会出现在命名或者多字符保留符号里面。注释可能出现在任何命名合法的地方;C语言和PL/I语言中,它们会被/* ... */包裹。

规则rules部分由一个或多个语法规则。一个语法规则有这样的格式:

A : BODY;

A代表一个非终止符的命名,BODY代表零值或者其他命名和字面量的顺序。冒号和分号是yacc的标点符号。

命名可能是任意长度的,并且由字母组成,点号".",下划线"_",还有非初始化数字。大写小写字母是独特的。一个语法规则体可能代表tokens或者非终止符号。

一个字面量包含一个被单引号" ' "。就像C语言,反斜杠""在字面量里面是一个逃逸字符,并且所有的C语言逃逸符号是公认的。因此:

        '\n'    newline
        '\r'    return
        '\''    single quote ``'''
        '\\'    backslash ``\''
        '\t'    tab
        '\b'    backspace
        '\f'    form feed
        '\xxx'  ``xxx'' in octal

因为很多技术原因,NUL字符('\0'或者0)在语法规则中从不应该被使用。

如果在左手边有很多个相同的语法规则,竖线"|"可以被用来避免重复写左手边。此外,一个规则的尾部的分号可以在一个竖线前被丢弃。因此语法规则:

        A       :       B  C  D   ;
        A       :       E  F   ;
        A       :       G   ;

可以给yacc提供成这样

        A       :       B  C  D
                |       E  F
                | 

没必要所有的左侧相同的语法规则一起出现在语法规则部分,尽管这样可以让输入变得更可读,并且修改更简单。

如果一个非终止符号匹配到空的字符串string,这种可以被表达成明显的方式:

        empty :  ;

命名代表了tokens必须被声明;这可以在声明(declarations)部分被书写得最简单。(看后面的第三、五、六章)

        %token   name1  name2 . . .

每一个在声明(declarations)部分未被定义到的命名name会被假定为一个非终止符号。每一个非终止符号必须出现在至少一个规则的左侧。

对所有的非终端符号来说,第一个被称为起始符号,有特别的重要性。解析器parser被设计来识别开始符号;因此,这个符号代表了被语法规则描述的最长,最通用的结构。默认来说,起始符号是在rules规则模块的第一个语法规则的左侧。在声明(declarations)模块明确声明起始符号很可能,事实上也可取,使用%start 关键词:

        %start    symbol

parser解析器的输入结束事件由一个特殊的token来通知,称为结束标记。如果这些tokens符号指向(但是不包含)结束标记,形成一个结构来匹配开始符号,解析器parser函数在看到结束标记后返回它的调用者caller;它接收输入。如果结束标记出现在任何其他上下文中,这是一个错误error。

用户提供的词法分析器的工作职责是在合适的时候返回结束标记;看下面的第三章。通常结束标记代表一些合理的明显的I/O状态,例如说"end-of-file"或者"end-of-record"。

未完待续...