gpt4 book ai didi

c - 我应该为不同类型的整数创建多少个标记?

转载 作者:太空宇宙 更新时间:2023-11-04 08:01:02 25 4
gpt4 key购买 nike

我正在尝试为具有这些类型的整数的语言实现词法分析器:

int32
整数64
uint32
uint64
sint32
sint64
固定32固定64位sfixed32
固定64

我的问题是:我应该为它们中的每一个创建一个不同的 token 吗?我是否也应该为每个人创建一个正则表达式?到目前为止,这是我的代码:

%{
enum Tokens{
L_INT = 1,
L_DOUBLE,
L_FLOAT,
L_BOOL,
L_STRING,
L_BYTE,
RW_REQUIRED,
RW_OPTIONAL,
RW_REPEATED,
RW_MESSAGE,
RW_IMPORT,
RW_PUBLIC,
RW_ENUM,
RW_SERVICE,
RW_CHANNEL,
RW_CONTROLLER,
A_RPAR,
A_LPAR,
C_RPAR,
C_LPAR
};
%}
%option nodefault noyywrap
%%
"(" { return A_RPAR; }
")" { return A_LPAR; }
"{" { return C_RPAR; }
"}" { return C_LPAR; }
"required" { return RW_REQUIRED; }
"optional" { return RW_OPTIONAL; }
"repeated" { return RW_REPEATED; }
"message" { return RW_MESSAGE; }
"import" { return RW_IMPORT; }
"public" { return RW_PUBLIC; }
"enum" { return RW_ENUM; }
"service" { return RW_SERVICE; }
"channel" { return RW_CHANNEL; }
"controller" { return RW_CONTROLLER; }
"true" { return L_BOOL; }
"false" { return L_BOOL; }
[\r\n ] {}
([0-1]) { printf("[%s]", yytext); return L_BYTE; }
(0|[1-9][0-9]*) { printf("[%s]", yytext); return L_INT; }
(0|[1-9][0-9]*)?\.[0-9]+ { printf("[%s]", yytext); return L_DOUBLE; }
(0|[1-9][0-9]*)?\.[0-9]+[fF] { printf("[%s]", yytext); return L_FLOAT; }
([a-zA-Z]*[0-9]*) { printf("[%s]", yytext); return L_STRING; }
. { printf("caractere invalido [%s] \n", yytext); return 0;}
%%
extern FILE *yyin;
int main (int argc, char* argv[]) {
int token = -1;
if (argc <2){
printf("Exemplo: %s [arquivo_entradas]",argv[0]);
return 1;
}
yyin = fopen(argv[1], "r");
while(token = yylex()) {
printf("Token = %d\n", token);
}
return 0;
}

最佳答案

除非您要坚持以类似 C 的方式编写整数并带有某种类型后缀——就像您似乎对 float 所做的那样——否则词法分析器绝对无法真正做到例如,判断给定的正整数是否是有符号类型的实例。所以我的想法是它甚至不应该尝试。

当然,您可以根据整数的大小以及它是否有符号进行部分分析,但最终整数可以(大概)用作它适合的任何类型的值成,所以 12 可以是您列出的 10 种类型中的任何一种。 (它也可能用作 float 。)所以部分分析实际上不会告诉您任何关于您的语言的语法 的必要信息,这会浪费词法分析器的工作。

这留下了一个悬而未决的问题,即如何表示整数的语义值,因为这些类型的所有 10 种可能值的并集无法放入 64 位中。 (范围从 -263 到 264-1。)如果您的语言允许算术表达式,您可以通过考虑 - 始终是一个运算符,而不是文字整数的一部分。然后整数的可能合法值适合无符号 64 位整数(uint64_t in C)的范围,这是一种合理的语义值类型。

由于您的语义值还包括 float ,因此您需要使用某种可区分的 union ;您还可以使用该机制来记录整数是否用符号写入(这与作为带符号的值不同),但这对我来说似乎很笨拙。无论如何,它可能与语法无关,除非你的语法有一些极端情况,其中只允许整数常量(没有表达式)但常量可以是负数。我也会避免此类句法规则。

我注意到您的代码试图将 0 和 1 具体归类为“字节”(尽管“位”似乎更准确),但我建议您也不要这样做。你仍然需要一个语义值来区分 0 和 1,并且这些常量中的任何一个都可以在非 bool (语法)上下文中使用,所以你并没有真正通过生成来给自己买任何东西一个不同的词法标记。

当您最终进行语义分析时,您将需要根据派生数据类型对语义值进行范围检查。如果您愿意,可以让词法分析器计算每个整数的范围类别,将其存储在语义类型结构的另一个成员中。但这可能不值得麻烦。

关于c - 我应该为不同类型的整数创建多少个标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46841169/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com