我试图理解编译器中“lexeme”和“token”之间的区别。
如果我的编译器的词法分析器部分在要编译的源代码中遇到以下字符序列。
"abc"
上面的词素长度为 5 个字符,这样说是否正确?
如果我的编译器是用 C 实现的,并且我为该词素的标记分配空间,则该标记将是一个结构。该结构的第一个成员将是一个 int
,它将具有某个枚举的类型,在本例中为 STRING_LITERAL。该结构的第二个成员是一个 char *
,它指向一些(动态分配的)具有 4 个字节的内存。第一个字节是'a'
,第二个'b'
,第三个'c'
,第四个是NULL
终止字符串。
所以...
词位是源代码文本的 5 个字符。
token 在内存中总共有 6 个字节。
这是使用术语的正确方法吗?
(我忽略跟踪文件名、行号和列号等元数据的标记。)
相关问题排序:
让词法分析器将整数词素转换为标记中的整数值是不常见的做法吗?或者将词位的字符存储在标记中并让解析器阶段将这些字符转换为要附加到 AST 的整数节点是否更好(或更标准)?
最佳答案
“词位”是源中的文字字符,例如“a”是“abc”中的词位。它是最小的单位。 “词法分析器”或词法分析阶段将词素转换为标记(例如关键字、标识符、文字、运算符等),这是解析器可用于创建 AST 的最小单位。所以如果我们有这样的声明
int x = 0;
词法分析器会输出
<type:int> <id: x> <operator: = > <literal: 0> <semicolon>
词法分析器通常是正则表达式的集合,可以简单地将字符集合定义为语言语法中的终结符。这些被转换为标记,并作为流输入到解析器中。
但是,大多数人可以互换使用词位和标记,并且通常不会造成混淆。对于有关转换 int 文字的问题,您需要为 AST 提供一个包装类。仅拥有一个整数可能不足以提供足够的信息。
关于parsing - "Lexeme"与 "Token"术语,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50940142/