通用类型签名的 Flex Bison 解析

Flex Bison parsing of a Generic type signature

我是 Flex/Bison 的新手。我正在尝试为支持泛型类型的简单编程语言编写解析器。

我想像这样解析一行:

fn foo(Vector<Pair<int, Array<T>>) -> void {}

我可以想象如何为 Vector<Pair<int, Array<T>> 编写一个手工制作的解析器。我会跟踪我遇到的 < 的数量,并将它与我遇到的 > 的数量相匹配,以确定类型规范是否完整。

对于类型,我认为语法规范应该是这样的?

TYPE : ID | ID '<' TYPE '>'
     ;

我不确定 TYPE 是由 Flex 还是由 Bison 生成的令牌。

我的理解是:

我的方向对吗?

注意:该项目仅用于我的教育目的。不是家庭作业等

您的方向是正确的,但学习一些正确的术语很有用。了解术语将有助于您理解和使用包含更多有用信息的教科书。

在规则 TYPE 中,名称 ID 将被称为 终端 符号,而 TYPE 将被称为 非终结符 文法 的符号。 语法 是用于描述语言的一组规则。每个语法规则定义一个 非终结符 符号。最终,每个 非终结符 将被描述为 终结符 符号在唯一(非歧义)排列中的排列。

terminal 符号由 token 表示,代表其具体表示形式。具体表示是实际在键盘上键入的内容。构成具体表示的字符序列称为 lexeme。匹配词位以创建标记是由词法分析器(或扫描仪)。标记序列与语法规则中的 非终结符 的匹配称为 parsing.

Flex 是生成词法分析器的工具,bison 是生成解析器的工具。

所以,TYPE 不是记号而是非终结符号(也称为语法规则名称)。它不是 flex 或 bison 的 "produced",而是语法的作者。 bison 生成的解析器将 reduce terminalsnon-terminals 的序列到 非终端调用了TYPE

为了避免混淆令牌终端非终端rules 有一个不成文的约定,即 tokensterminal 符号要么以大写形式书写,要么作为字符常量书写。例如:

ID, '<'

非终结符语法规则都写成小写以避免与前者混淆。例如:

type, expression

因此,有经验的 bison 用户可能会写:

type_signature : ID 
     | ID '<' type_signature '>'
     ;

这样每个名字的性质就更清楚了。

现在讨论空白。不,flex 和 bison 不会忽略(自动或其他方式)空格、制表符、换行符、回车 returns 和其他不可见字符,但它很复杂(正如你的问题)。

有出现在词法分析器处理的具体表示中的空白字符,也有出现在flex和bison工具描述语言处理的规则集中出现的空白字符。您希望处理的语言可能包含语法上(甚至语义上)重要的空白字符(一个极端的例子是名为 WhiteSpace 的语言)。可以使用 flex 和 bison 为该语言编写解析器,因此它不能忽略其输入描述文件或输入语言中的所有空格!在这里不做过多的介绍,只是值得注意的是,在某些地方空白被忽略,而在其他地方它特别重要;在更有经验之前,您应该小心。词法分析器规则文件中的空格比解析器规则文件中的空格更敏感。