LBNF,C函数声明/定义,减少冲突
LBNF, C function declaration / definition, reduce reduce conflict
我试图在LBNF中表示C/C++函数声明具有以下(近似)形式(<sym>
表示可选性,[rule]是零或更多列表):
type ident ( [type <id>] );
而函数定义的形式是:
type ident ( [type id] ) { [stmt] }
目前,我有以下LBNF:
entrypoints Program ;
Program. Program ::= [TopDef] ;
FnDef. TopDef ::= Type Ident "(" [Arg] ")" Block ;
FnDecl. TopDef ::= Type Ident "(" [Par] ")" ";" ;
separator nonempty TopDef "" ;
Param. Par ::= Type ;
NParam. Par ::= Type Ident ;
separator Par "," ;
Arg. Arg ::= Type Ident;
separator Arg "," ;
-- Types ---------------------------------------------------
Int. Type ::= "int" ;
--- more types...
separator Type "," ;
这会按预期减少/减少冲突。有没有一种方法可以在解析器/lexer中解决这个问题?
我可以用以下语法来解决它:
FnDef. TopDef ::= Type Ident "(" [Arg] ")" Block ;
FnDecl. TopDef ::= Type Ident "(" [Arg] ")" ";" ;
separator nonempty TopDef "" ;
Arg. Arg ::= Type Ident;
Arg. Arg ::= Type;
separator Arg "," ;
然后在类型检查器中检查函数定义是否为每个参数都有标识符,但这感觉不太令人满意。。。
在像C这样的语言中,这通常是如何处理的?
您提到的不令人满意的方式实际上是通常完成的方式。
但是你可以生成一个精确的LALR(1)语法。这里有一个完整的野牛规范,没有冲突:
%token TYPE ID
%%
prog :
| prog decl ';'
decl : TYPE ID def_list block
| TYPE ID def_list ';'
| TYPE ID dec_list ';'
block : '{' prog '}'
def_list : '(' ')'
| '(' type_ids ')'
dec_list : '(' type_opt_ids ')'
type_opt_id: type_only
| type_id
type_ids : type_id
| type_ids ',' type_id
type_opt_ids
: type_only
| type_ids ',' type_only /* SEE BELOW */
| type_opt_ids ',' type_opt_id
type_id : TYPE ID
type_only : TYPE
关键是要避免强迫解析器做出决定。当它传递参数列表时,只要不碰到匿名参数,它就可以不断减少type_opt_ids
。如果它达到一个,它将减少一个type_ids
,并继续处理其余参数,无论它们是否匿名。最后,定义只允许type_ids
,但声明(显式)接受其中任何一个。
为了实现这一点,type_id
和type_only
的语义类型需要相同,因为type_ids
和type_opt_ids
都必须是该类型的列表。否则,您需要在标有/* SEE BELOW */
的产品中将type_ids
转换为type_opt_ids
(我很抱歉没有把它转换成你的形式主义,但我想用野牛测试它,以验证它实际上是没有冲突的。转换应该足够容易。)
请注意,C++很乐意允许不带参数名称的函数定义,但C则不然。另一方面,C允许函数定义没有类型,或者在参数名称列表和主体之间有类型声明。但这确实是个次要问题。
相关文章:
- VS2017 #error: : snprintf 的宏定义与标准库函数声明冲突
- C++哈希表 - 如何解决自定义数据类型作为键的unordered_map冲突?
- Visual Studio:snprintf 冲突的宏定义
- 冲突声明/重新定义:不同的基本类型
- 是否有具有用户定义的冲突处理程序的 std::唯一样式库算法
- GCC 6.3.0 中的 ODR 冲突,类型在两个单独的翻译单元中定义
- C++冲突声明的标准定义
- 在Visual Studio中定义与Typedef枚举发生冲突的原因是什么?
- 全局重新定义多个冲突的预处理器定义
- 如何修复与Xtime的Boost和Vs相互冲突的定义有关的编译器错误
- 包含:stdafx.h 和 <vector> VisualStudio 2012 C++ 之间的冲突(错误 C2953:已定义类模板)
- 将使用预处理器指令来定义美元符号表示的内容会导致任何冲突
- C++类型定义与类冲突
- OpenGL重新定义错误与Windows SDK文件相冲突时
- 相同定义变量的部分类型冲突
- directx标头和winerror.h之间的宏定义冲突
- LBNF,C函数声明/定义,减少冲突
- 创建具有自动存储的自定义对象并推送回 std::vector 时访问冲突
- 包括 Windows 标头与用户定义的类名冲突
- 为访问冲突定义条件断点