Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ocamlmenhir中,如何为C++/Rust/Java风格的泛型 在C++中,一个著名的解析模糊现象发生在类似的代码中。 x<T> a; xa;_Ocaml_Menhir - Fatal编程技术网

在ocamlmenhir中,如何为C++/Rust/Java风格的泛型 在C++中,一个著名的解析模糊现象发生在类似的代码中。 x<T> a; xa;

在ocamlmenhir中,如何为C++/Rust/Java风格的泛型 在C++中,一个著名的解析模糊现象发生在类似的代码中。 x<T> a; xa;,ocaml,menhir,Ocaml,Menhir,如果T是一个类型,它就是它的样子(类型x的变量a的声明,否则它就是(xa(是比较运算符,而不是尖括号) 事实上,我们可以做一个改变,使其变得明确:我们可以使 AFAIK C++的模板语法是真实世界非LR语法的一个著名例子。严格来说,它不是任何有限k的LR(k)。所以C++分析器通常是用HACK(如CLAN)手写的,或者由GLR语法(LR分支)生成。理论上,在Menhir中实现一个完整的C++解析器是不可能的,即LALR. 但是泛型的语法也可以是不同的。如果泛型类型和包含比较运算符的表达式在同一上

如果
T
是一个类型,它就是它的样子(类型
x
的变量
a
的声明,否则它就是
(xa
是比较运算符,而不是尖括号)

事实上,我们可以做一个改变,使其变得明确:我们可以使
非关联。因此
xa
,没有括号,即使
x
T
a
都是变量名,也不会是一个有效的句子


如何在Menhir中解决这一冲突?乍一看,我们似乎无法解决。即使进行了上述修改,在看到另一个结束之前,我们需要先查看不确定数量的标记,然后才能得出结论,这是一个模板实例化,或者以其他方式得出结论,这是一个表达式。是否存在在Menhir中,实现这种任意的前瞻性是什么?

< P> AFAIK C++的模板语法是真实世界非LR语法的一个著名例子。严格来说,它不是任何有限k的LR(k)。所以C++分析器通常是用HACK(如CLAN)手写的,或者由GLR语法(LR分支)生成。理论上,在Menhir中实现一个完整的C++解析器是不可能的,即LALR.

但是泛型的语法也可以是不同的。如果泛型类型和包含比较运算符的表达式在同一上下文中不会出现,则语法可能仍然是LR兼容的。例如,考虑变量声明的Rice语法(仅针对这一部分):

让x:Vec=。。。
标记表示后面是类型,而不是表达式,因此在本例中,语法可以是LR,甚至是LL(未验证)


<> P> >最后,我们的答案是,这取决于。但是对于C++的情况,在MHIHIR中不可能实现语法。<> P> AFAIK C++的模板语法是真实世界非LR语法的一个著名例子。严格来说,对于任何有限的K,它不是LR(k)。所以C++分析器通常是用HACK(如CLAN)手写的。或者由GLR文法生成(分支),所以在Menhir中不可能实现完整的C++分析器,即LALR.

但是泛型的语法也可以是不同的。如果泛型类型和包含比较运算符的表达式在同一上下文中不会出现,则语法可能仍然是LR兼容的。例如,考虑变量声明的Rice语法(仅针对这一部分):

让x:Vec=。。。
标记表示后面是类型,而不是表达式,因此在本例中,语法可以是LR,甚至是LL(未验证)

<> P> >最后的答案是,这取决于。但是对于C++的情况,在MHIHIR中不可能实现语法。

< P>不同的语言(包括在你的标题中列出的)实际上有不同的模板/泛型规则。(比如可以有什么类型的参数,模板/泛型可以出现在哪里,何时允许它们有一个显式的参数列表,以及泛型方法上模板/类型参数的语法是什么),这会强烈影响解析选项。在我所知的任何语言中,
xa;
的含义都取决于
T
是否为类型

<> P>让我们通过C++语言、java语言、Rust语言和C语言:

在这四种语言中,类型和函数/方法都可以是模板/泛型的。因此,我们不仅要担心变量声明的模糊性,还要担心函数/方法调用:is
f(x)
带有显式模板/类型参数的函数/方法调用,还是带有最后一个操作数括号的两个关系运算符?在所有四种语言中,如果可以推断模板/泛型函数/方法,则可以在没有模板/类型的情况下调用这些函数/方法,但这种推断并不总是可能的,所以只需禁止显式模板/类型a即可函数/方法调用的参数不是选项

即使一种语言不允许将关系运算符链接起来,我们也可能会在表达式中出现歧义:
f(a(e))
。这是使用三个参数
ae
调用
f
还是使用单个参数
a(e)
使用类型/模板参数调用名为
a
的函数/方法
b、c、d

现在除了这个共同的基础,大多数其他语言在这些语言之间是不同的:

生锈 在Rust中,变量声明的语法是
let variableName:type=expr;
,因此
x a;
不可能是变量声明,因为它与语法完全不匹配。此外,它也不是有效的表达式语句(不再),因为比较运算符无法链接(不再)

因此这里没有歧义,甚至没有解析困难。但是函数调用呢?对于函数调用,Rust通过简单地选择不同的语法来提供类型参数来避免歧义:而不是
f(x)
语法是
f::(x)
。由于函数调用的类型参数在可以推断的情况下是可选的,所以谢天谢地,这种丑陋的情况并不经常出现

总之:
让a:x=…;
是一个变量声明,
f(a(e));
用三个参数调用
f
,用三个类型参数调用
f(a:(e));
调用
a
。解析很容易,因为所有这些都非常不同,只需一个先行标记即可区分

JAVA 在Java
x中;
实际上是一个有效的变量声明,但它不是一个有效的表达式语句