我熟悉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语法规则有错?
似乎GCC和LLVM-Clang使用手写递归下降解析器,而不是机器生成,基于Bison-Flex,自下而上解析.
请问有人请确认是这种情况吗?如果是这样,为什么主流编译器框架使用手写解析器?
更新:这里有关此主题的有趣博客
或者,更准确一点:哪些编程语言是由无上下文语法定义的?
从我收集的内容来看,由于宏和模板之类的东西,C++不是无上下文的.我的直觉告诉我,函数式语言可能没有上下文,但我没有任何硬数据来支持.
额外的代表简洁的例子:-)
我几个月前在D新闻组上发布了这个,但由于某种原因,答案从未真正说服过我,所以我想我会在这里问.
但是,C++的语法不是(即使没有宏).(请仔细阅读!)
现在被授予,我对编译器,词法分析器和解析器一无所知(正式).我所知道的只是我在网上学到的东西.
以下是(我相信)我对上下文的理解,在非技术术语中:
语言的语法是无上下文的,当且仅当你能够总是理解给定代码片段的含义(尽管不一定是确切的行为)而不需要在任何其他地方"看".
或者,更严格:
如果我需要,语法不能无上下文我只是通过查看它就无法告诉表达式的类型.
因此,例如,C++失败上下文测试,因为意义的confusing<sizeof(x)>::q < 3 > (2) 依赖于值的q.
到现在为止还挺好.
现在我的问题是:可以对D说同样的话吗?
例如,在D中,可以通过Value[Key]声明创建哈希表
int[string] peoplesAges; // Maps names to ages
Run Code Online (Sandbox Code Playgroud)
静态数组可以用类似的语法定义:
int[3] ages; // Array of 3 elements
Run Code Online (Sandbox Code Playgroud)
模板可以用来使它们混淆:
template Test1(T...)
{
alias int[T[0]] Test;
}
template Test2(U...)
{
alias int[U] Test2; // LGTM
}
Test1!(5) foo;
Test1!(int) bar;
Test2!(int) baz; // Guess what? It's …Run Code Online (Sandbox Code Playgroud) 有什么好的工具可以快速开始解析和分析C/C++代码?
特别是,我正在寻找处理C/C++预处理器和语言的开源工具.优选地,这些工具将使用lex/yacc(或flex/bison)用于语法,并且不会太复杂.他们应该处理最新的ANSI C/C++定义.
这是我到目前为止所发现的,但没有详细查看它们(想法?):
我希望将此作为将C/C++源代码翻译成新玩具语言的起点.
谢谢!-Matt
(已添加2/9):只是澄清:除了C/C++代码本身之外,我还希望从预处理器中提取语义信息.我不希望"#define foo 42"消失在整数"42"中,但仍然附加到名称"foo".不幸的是,这排除了几个首先运行预处理器并且只提供C/C++解析树的解决方案.
人们说这话时意味着什么?对程序员和编译器有什么影响?
该标准是否指定了官方C++语法?
我搜索过,但没找到任何地方.
另外,我希望详细阅读一些关于C++语法的内容,比如它所属的语法类别等等.任何指向正确方向的链接都会有所帮助.
按类别,我的意思是
取自这里.
c++ standards grammar context-free-grammar chomsky-hierarchy
可能重复:
C++是无上下文还是上下文相关?
对于熟悉编译器的人来说,这可能是一个愚蠢的问题,但老实说我对答案一无所知.
C++语法是上下文敏感的吗?换句话说,C++语法是否无法用无上下文语法表达?
很明显,C++ 是使用常规解析工具解析的,并且解析并不是特别无效(!),但我确实记得读过这个(我不记得在哪里),我想我会在传播之前直接了解社区谎言......也许C++的一个子集是CS?也许新的规格?任何帮助表示赞赏.
编辑:感谢所有的回复.但是,为了完整起见,编译的哪个部分处理歧义?CFG是一种语法,在规则的左侧只有一个非终端符号(例如A->zC),CSG是在左侧有一个终端(加上一个非终端)的语法(aAv->QT),其中大写字母是非终结符,小写是终结符.在解析 C++源代码的语法中是否有像后者那样的表示?
我试过的所有编译器都正确拒绝了代码
int main() {
int x = "foo";
}
Run Code Online (Sandbox Code Playgroud)
带有类型错误:const char[4]无法转换为int.为什么相同的编译器(包括Ideone.com)会给出相同的错误
int main() {
int x = + "foo";
}
Run Code Online (Sandbox Code Playgroud)
而不是(我想到的)语法错误因为+符号?我的第一个想法是const char[4]衰减指针,而指针又被视为一个整数值,因此+表示"正".虽然看起来有点牵强,但我希望看到const char*出现在错误消息中.
为了更好地理解C++语言和语法的一些细节,我希望能够编写一个小的C++程序,并查看编译器从中生成的AST.
看起来clang过去有这个功能(-emit-asm),但它已经删除了.
今天有一个简单的方法吗?