Compiler construction 在编译器构造中使用标记或字符串有什么区别吗?

Compiler construction 在编译器构造中使用标记或字符串有什么区别吗?,compiler-construction,compiler-optimization,lexical-analysis,javacc,Compiler Construction,Compiler Optimization,Lexical Analysis,Javacc,我曾试图用JavaCC优化编译器,但后来遇到了一些过去在使用编译器时从未发现的东西,因为我被教导对任何终端使用令牌 此编译器有时在语法分析的正则表达式中使用字符串而不是标记,例如: <TK_IF> "(" log_expr ")" body “(“log_expr”)”正文 而不是: <TK_IF> <TK_LPAREN> log_expr <TK_RPAREN> body log\u expr body 这只是一个示例,在代码的其他部分中

我曾试图用JavaCC优化编译器,但后来遇到了一些过去在使用编译器时从未发现的东西,因为我被教导对任何终端使用令牌

此编译器有时在语法分析的正则表达式中使用字符串而不是标记,例如:

<TK_IF> "(" log_expr ")" body
“(“log_expr”)”正文
而不是:

<TK_IF> <TK_LPAREN> log_expr <TK_RPAREN> body
log\u expr body

这只是一个示例,在代码的其他部分中,在操作符中使用字符串,如(+、-、!=、=、=、>,,在过去,实现lexer/tokenizer是很常见的,以便它们为每个令牌类型号返回“小整数”值:

IF the next token is the word "def" THEN RETURN 257 FI
例如,结合使用7位或8位字符集,我们可以立即看到所有256个可能的字符值都可以作为令牌值使用。因此“
”只能是令牌编号40(请参见任何ASCII表)

您通常可以判断是否有人在使用这种表示法,因为像
+
这样的单字符运算符将以这种方式编码(
+
=43),但像
+=
这样的双字符运算符将有一个命名令牌。当生成令牌查找代码的代码生成令牌表,并且第一个命名令牌的数值略高于255(最大8位值)时,会出现另一个赠品


最后,这并不是很重要:这只是一个实现难题。如果您编写自己的扫描器和解析器,您将尽一切可能将适当的令牌代码返回到解析器。如何将一些输入语法转换为适当的代码取决于您。

在过去,实现lexer/tok是很常见的对每个令牌类型编号进行加密,以便返回“小整数”值:

IF the next token is the word "def" THEN RETURN 257 FI
例如,结合使用7位或8位字符集,我们可以立即看到所有256个可能的字符值都可以作为令牌值使用。因此“
”只能是令牌编号40(请参见任何ASCII表)

您通常可以判断是否有人在使用这种表示法,因为像
+
这样的单字符运算符将以这种方式编码(
+
=43),但像
+=
这样的双字符运算符将有一个命名令牌。当生成令牌查找代码的代码生成令牌表,并且第一个命名令牌的数值略高于255(最大8位值)时,会出现另一个赠品

最后,这并不是很重要:这只是一个实现难题。如果您编写自己的扫描器和解析器,您将尽一切可能将适当的标记代码返回到解析器。如何将一些输入语法转换为适当的代码取决于您。

答案在后面

假设我有两个定义(或JavaCC术语中的词法结果)

但是------由于
变成了
令牌类型只能引用字符串
:=
——并且可能是唯一这样的令牌类型,JavaCC允许您将这个BNF产品编写为

void assignment() : {} { <ID> ":=" expression() }
void赋值():{}{:=“expression()}
这两种书写作品的方式是相同的

在您的例子中,非终端产品中的字符串“(”和“)”只是分别缩写为

此缩写只能用于BNF制作。

答案在中

假设我有两个定义(或JavaCC术语中的词法结果)

但是------由于
变成了
令牌类型只能引用字符串
:=
——并且可能是唯一这样的令牌类型,JavaCC允许您将这个BNF产品编写为

void assignment() : {} { <ID> ":=" expression() }
void赋值():{}{:=“expression()}
这两种书写作品的方式是相同的

在您的例子中,非终端产品中的字符串“(”和“)”只是分别缩写为


这个缩写只能在BNF产品中使用。

欢迎这么做!我认为这完全是一个非优化问题——您使用的任何解析器生成器都会有相同的行为,并内联所有终端/从语法编译正则表达式。您有什么性能问题需要搜索微优化类似这样的定义?正则表达式是bnf语法的一个简化的和虚构的子集,所以它可能只是一个符号。@MarcovandeVoort不,它不是。它是一个完全不同的东西,有一些额外的特性,也有一些bnf中缺少的特性。正则表达式历史上早于bnf。我指的是在标记器中使用的子集。请注意,许多e最近从PCRE中捕获的功能并不早于BNF。@ggorlen,我正在使用的这个编译器必须随着时间的推移处理新的功能,所以它是一个补丁。我的目标是对它进行重构,以提高性能、可读性等。正因为如此,我正在寻找编译器构造的最佳实践,但我在web上找不到它。Wel这么说吧!我认为这完全是一个非优化问题——您使用的任何解析器生成器都会有相同的行为,并内联所有终端/根据语法编译正则表达式。您有什么性能问题需要搜索这样的微优化?正则表达式是bn的简化和预制子集f语法,所以它可能只是符号。@MarcovandeVoort不,它不是。它是一个完全不同的东西,有一些额外的功能,也有一些BNF中缺少的功能。正则表达式历史上早于BNF。我指的是标记器中使用的子集。请注意,最近从例如PCRE中捕获的许多功能并不早于BNF.@ggorlen,我正在使用的这个编译器必须随着时间的推移处理新的功能,所以它是一个补丁。我的目标是重构它,以提高性能、可读性等。正因为如此,我正在寻找编译器构造的最佳实践,但我可以