BUAA-SE-Compiling / miniplc0-handbook

miniplc0 指导书
https://mini.buaasecompiling.cn
22 stars 6 forks source link

词法分析器是否要处理 无符号整数溢出 的问题 #6

Closed Zx55 closed 4 years ago

Zx55 commented 5 years ago

根据 指导书 无符号整数的溢出属于语义错误 但是 tokenizer.cpp中的指导需要将无符号整数token转化为整数

假设有一个数10^1000 该数明显溢出,显然无法正确转化为整数,这里就属于指导中的解析错误,应该报错,所以词法分析器是要处理这个语义错误吗?还是无视溢出,作为std::string返回;交给语法分析器

此外error.h中只有int32_t的溢出错误码,没有uint32_t的溢出错误码,是要自行添加吗?

fazdzz commented 5 years ago

假设有一个数10^1000 该数明显溢出,显然无法正确转化为整数,这里就属于指导中的解析错误,应该报错,所以词法分析器是要处理这个语义错误吗?还是无视溢出,作为std::string返回;交给语法分析器

这是一个何时进行错误发现、捕获和处理的问题, mio 在实现时选择了在词法分析进行处理,我们认为在这里直接进行转换是比较方便的。你当然也可以不进行转换,而是在其他阶段进行处理。

此外error.h中只有int32_t的溢出错误码,没有uint32_t的溢出错误码,是要自行添加吗?

mio 在代码注释 int32_t overflow 。个人猜测是因为指导书中要求的无符号整数值域是 std::int32_t 的子区间,因此他在实现时是直接判断 std::int32_t 了。如果这里改成 std::uint32_t, 显然会超出指导书要求的值域。

wtdcode commented 5 years ago

感谢参与实验设计。

首先引用请按照 mainpage 的说明引用 permanent links。

1 这个问题很灵活,词法分析或者语法分析都可以 2 文法要求的溢出区域要小一些,见这里,因此对于无符号整数只要超过了 INT32_MAX 必然是(语义限制上的)溢出所以特指了 int32_t,反之亦然 3 错误码可以随意修改

Zx55 commented 5 years ago

有一个问题:最终的评判是不分阶段、完整的测试吗? 如果分阶段测试,即单独测试词法分析器和语义分析器,那么在何处实现溢出处理的问题会导致输出的不一致

标程是在词法分析阶段解决的溢出问题,那么词法分析阶段就应该报错 若是在语法分析阶段解决溢出问题,词法分析阶段就直接保留了string,直接输出了一个溢出的数的字符串 两边不一致,导致出错

fazdzz commented 5 years ago

最终的评判是不分阶段、完整的测试吗?

是的,中间的词法/语法分析的测试我们只会提供测试用例供大家自测,最终我们考虑的是编译器输出的程序对不对,以及不符合文法/语义规则的编译错误有没有合适地报错(怎么报错,报什么错不在考虑范围内),对于未定义行为不会进行测试(但也有可能我们漏了一些应该报错的情况)

Zx55 commented 4 years ago

一个新的问题

假设以下整数长度都是4位 32位同理

指导书中语义限制 这里无符号数的限制应该对应是[0, 2^3 - 1] = [0, 7]

但是根据补码它的范围是 [-8, 7],那么最后-8肯定是会漏掉

所以这边读到-8是做溢出处理还是将指导书上的限制扩大为[0, 8]? 至于+8的溢出则交出语法分析来处理

我的想法是既然它是int4,就应该符合int4的范围[-8, 7],也就是要改指导书上一开始读进来无符号数的范围到[0, 2^3]

fazdzz commented 4 years ago

一个新的问题

假设以下整数长度都是4位

指导书中语义限制 这里无符号数的限制应该对应是[0, 2^3 - 1] = [0, 7]

但是根据补码它的范围是 [-8, 7],那么最后-8肯定是会漏掉

所以这边读到-8是做溢出处理还是将指导书上的限制扩大为[0, 8]? 至于+8的溢出则交出语法分析来处理

如果让符号成为整数字面量token的组成部分,会有歧义,这样的情况下词法分析读到减号会无法直接判断它是负号还是减号,而让词法分析依赖语法分析的语境的话就违背了为词法分析和语法分析解耦的初衷。之前有在论坛讨论过,但是中间数据丢了所以现在引用不了。

总之结论是,-8 应当视作两个token:MINUS_SIGN 和无符号整数 8 。如果写的没错,那么在语法分析阶段,不会存在 MINUS_SIGN 是负号还是减号的歧义。而 8 溢出了值域,什么时候处理和上面的回答说的一样,你自己说了算。

我理解你对于字节数的想法,最初我们要求字面量是uint32_t的值域,但是因为这个简单文法它的确承担不了这么大的值域,因此才将其砍到了int32_t的正数部分。至于要不要包含int32_t的最小值的相反数,这个我觉得你可以思考一下为什么C库定义 INT_MIN 的时候,一般用的是 -INT_MAX-1,而不是直接写数值。

并且从便利的角度出发,要求值域是在[0,7],一定可以避免隐含的+8溢出的问题。

有一个比较trick的事情是,在有高亮的IDE,输入一个我们看上去是负整数的字面量。你一般会发现,符号的颜色会跟其他运算符一样,而和数字部分的颜色不一样。

wtdcode commented 4 years ago

这里你思考的方向反了,你看到值域首先想的应该是用多大的结构能去表示,而不是这个结构没表示到的数字。

打个比方,如果我没记错 cpp 的 int 标准定义值域是没有 2**31-1那么大的。


From: Hambaka notifications@github.com Sent: Tuesday, November 12, 2019 10:08:01 AM To: BUAA-SE-Compiling/miniplc0-handbook miniplc0-handbook@noreply.github.com Cc: Mio ziqiaokong@outlook.com; Comment comment@noreply.github.com Subject: Re: [BUAA-SE-Compiling/miniplc0-handbook] 词法分析器是否要处理 无符号整数溢出 的问题 (#6)

一个新的问题

假设以下整数长度都是4位

指导书中语义限制https://github.com/BUAA-SE-Compiling/miniplc0-handbook/blame/8174750ab40eba35ed63c68bd6f0ae9484268e3a/Readme.md#L429 这里无符号数的限制应该对应是[0, 2^3 - 1] = [0, 7]

但是根据补码它的范围是 [-8, 7],那么最后-8肯定是会漏掉

所以这边读到-8是做溢出处理还是将指导书上的限制扩大为[0, 8]? 至于+8的溢出则交出语法分析来处理

如果让符号成为整数字面量token的组成部分,会隐藏歧义,这样的情况下词法分析读到减号会无法直接判断它是负号还是减号,而让词法分析依赖语法分析的语境的话就违背了为词法分析和语法分析解耦的初衷。之前有在论坛讨论过,但是中间数据丢了所以现在引用不了。

总之结论是,-8 应当视作两个token:MINUS_SIGN 和无符号整数 8 。如果写的没错,那么在语法分析阶段,不会存在 MINUS_SIGN 是负号还是减号的歧义

我理解你对于字节数的想法,最初我们要求字面量是uint32_t的值域,但是因为这个简单文法它的确承担不了这么大的值域,因此才将其砍到了int32_t的正数部分。至于要不要包含int32_t的最小值的相反数,这个我觉得你可以思考一下为什么C库定义 INT_MIN 的时候,用的是 -INT_MAX-1,而不是直接写数值

― You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/BUAA-SE-Compiling/miniplc0-handbook/issues/6?email_source=notifications&email_token=AHJULO6GY22ZAXPUMXVRFE3QTIFYDA5CNFSM4JLLCOHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDYYZPA#issuecomment-552701116, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJULO5ISVANRVKURSLZWIDQTIFYDANCNFSM4JLLCOHA.

fazdzz commented 4 years ago

这里你思考的方向反了,你看到值域首先想的应该是用多大的结构能去表示,而不是这个结构没表示到的数字。

这是从实现的角度考虑。如果是设计这个mini的语义的时候,必然是要考虑一个内存单元支持多大的数值比较方便。

打个比方,如果我没记错 cpp 的 int 标准定义值域是没有 2**31-1那么大的。

所以我才写的int32_t

wtdcode commented 4 years ago

我是从学生角度说的,不是从设计实验角度。


From: Hambaka notifications@github.com Sent: Tuesday, November 12, 2019 11:05:18 AM To: BUAA-SE-Compiling/miniplc0-handbook miniplc0-handbook@noreply.github.com Cc: Mio ziqiaokong@outlook.com; Comment comment@noreply.github.com Subject: Re: [BUAA-SE-Compiling/miniplc0-handbook] 词法分析器是否要处理 无符号整数溢出 的问题 (#6)

这里你思考的方向反了,你看到值域首先想的应该是用多大的结构能去表示,而不是这个结构没表示到的数字。

那这个从实现的角度,最开始设计这个mini的语义的时候,必然是要考虑一个内存单元支持多大的数值比较方便。

打个比方,如果我没记错 cpp 的 int 标准定义值域是没有 2**31-1那么大的。

所以我才写的int32_t

― You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/BUAA-SE-Compiling/miniplc0-handbook/issues/6?email_source=notifications&email_token=AHJULO27ZSSFLJDOZUYQGFLQTIMO5A5CNFSM4JLLCOHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDY32OI#issuecomment-552713529, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHJULOY4COFXVIAOKCC6XATQTIMO5ANCNFSM4JLLCOHA.

wtdcode commented 4 years ago

长时间没有新回复,暂且先 close,有问题及时 reopen。