如何在C#中解析括号,lambda和元组表达式

时间:2019-06-24 19:38:36

标签: c# parsing lambda tuples

我正在编写自己的编程语言,并且在排除了其他大部分内容之后,开始解析元组/ lambda表达式。语法非常类似于C#,但有一些区别。我想知道C#是否可以确定是否要生成一个简单的带括号的表达式(元组或lambda),因为前瞻(k)是不确定的。

现在,我通过偷看某些指标来为解决方案共同努力,这些指标应为解析器提供有关其试图解析内容的线索。也就是说,请检查@ 1的标识符,然后在@ 2处检查'=','或':'(冒号用于使用类型信息注释标识符)。

我的lambda语法比C#中的语法更加灵活,因此猜测其中,您可以仅解析标识符列表,直到不再有逗号为止,并检查下两个标记中的')'和'= >”。

我缺少某种技巧吗?

1 个答案:

答案 0 :(得分:1)

是的,您需要无限制的前瞻,因为在某些情况下,(a, b, c, ...)可以是元组,也可以是lambda参数的列表,具体取决于后面跟随的标记。还有一个歧义,因为(a.b.c.d...可以是类型转换中的类型表达式,也可以是带括号的正则表达式。

您可以在解析器源代码中看到C#如何解决此问题: http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp/Parser/LanguageParser.cs,bab23e84fb31bf9e,references

基本上,它保存当前位置并尝试解析可能的结果之一。如果解析失败,它将返回到保存的位置(也就是回溯),然后尝试下一次可能的生产。如果所有可能的制作均失败,则会报告语法错误。

似乎可以通过两遍运行潜在的解析。在第一遍中,它仅检查是否可以进行解析,并返回布尔值。如果此测试成功,它将运行第二遍,并在此实际构建解析树。

理论上,无限制的超前运行会破坏解析器的性能,但是实际上,这可能不是一个大问题,因为它仅在某些特定的上下文中发生,并且元组和lambda参数列表的大小通常有限。

语言设计者倾向于避免语法要求超前,因为它增加了解析器的复杂性和性能影响。但是C#的设计师可能认为,花钱添加漂亮的元组语法值得。