我熟悉C和C++的语法是上下文相关的事实,特别是你需要在C中使用"lexer hack".另一方面,我的印象是你只能解析Java尽管两种语言之间存在相当大的相似性,但仍有2个前瞻性令牌.
你需要改变什么才能使它更易于解析?
我问,因为我所见过的关于C的上下文敏感性的所有例子在技术上都是允许的,但非常奇怪.例如,
foo (a);
Run Code Online (Sandbox Code Playgroud)
可以foo用参数调用void函数a.或者,它可以声明a是一个类型的对象foo,但你可以很容易地摆脱parantheses.在某种程度上,这种奇怪之处的发生是因为C语法的"直接声明者"生成规则实现了声明函数和变量的双重目的.
另一方面,Java语法具有用于变量声明和函数声明的单独生成规则.如果你写
foo a;
Run Code Online (Sandbox Code Playgroud)
然后你知道它是一个变量声明,foo可以毫不含糊地解析为一个类型名.如果foo尚未在当前作用域中的某处定义类,则这可能不是有效代码,但这是可以在稍后的编译器传递中执行的语义分析的工作.
我已经看到它说由于typedef很难解析C,但你也可以在Java中声明自己的类型.此外direct_declarator,哪种C语法规则有错?
我想问的问题在标题中简明扼要.让我举一个问题语法的例子:
identifier_list
: identifier
| identifier_list identifier;
lambda_arguments
: '(' identifier_list ')'
| identifier;
lambda
: lambda_arguments '=>' expression
Run Code Online (Sandbox Code Playgroud)
然后我们添加正常的C表达式语法 - 特别是
primary_expression
: '(' expression ')'
| identifier
| lambda;
Run Code Online (Sandbox Code Playgroud)
真正的问题是,这个语法LALR(1)是否可解析,即能够被自动解析器生成器解析?或者它需要手动或GLR解析器?请注意,我希望特别了解此小节,而不是上下文相关的关键字内容或任何其他部分.
我现在想的是,如果解析器看到'(' identifier ')',它有两个有效的解析,所以如果解析器看到identifier,向前看')',它将无法决定哪个解析树失效.这可能只是一个转移/减少冲突,我可以通过分配一些任意优先权(可能是有利的'(' identifier ')')来消除.
编辑:实际上,我正在考虑使用这个语法小节来窃取新语言中的类似功能.我已经在语法形式上有类似于JavaScript的匿名函数,但我的豚鼠吱吱声反馈抱怨它们对于许多用途而言过于冗长,并且指出C#lambda表达式是更理想的解决方案.我担心这个解决方案可能导致模糊不清.所以,真的,我只对那个小节感兴趣.其他东西,如泛型和演员表对我来说都不是问题.
以前版本的语法都是机械可解析的,我不想失去这个属性,而我之前使用机械发生器的经验告诉我,最好先检查这里,而不是试试自己.对于我的手动解析器,我当然可以通过特殊情况'(' identifier向前看比正常情况更进一步.
我曾经认为C++是"怪异"的一个与所有与歧义<和>,而是试图实现一个解析器我想我找到打破一个例子之后几乎每一个使用的语言<和>泛型类型:
f(g<h, i>(j));
Run Code Online (Sandbox Code Playgroud)
这可以在语法上解释为泛型方法call(g),也可以解释为给出f两次比较的结果.
这些语言(特别是Java,我认为应该是LALR(1) - 可解决的?)如何克服这种语法模糊性?
我无法想象任何非hacky/context-free方式来解决这个问题,我对这种语言如何无上下文感到困惑,更不用说LALR(1)-parsable ......
(值得注意的是,即使是GLR解析器也无法为此语句返回单个解析而没有上下文!!)
我在5.0版中寻找编程语言C#的EBNF语法.这个语法应该是机器可读的,所以我能够用这个EBNF语法做一些处理
到目前为止,我发现C#的语言规范文档包含在Visual Studio(%PROGRAMFILES(x86)%\Microsoft Visual Studio 12.0\VC#\Specifications\1033)的安装中,这个文档已经包含了文档中嵌入的BNF语法.但是,这只是在BNF语法中而不是EBNF,并且它在*.docx文档中嵌入了一个没有单独的文件,这意味着它对我来说还不够.
另外我找到了这些资源:
所以这些资源对我的项目来说还不够.你知道C#5.0的完整EBNF语法吗?