为什么这么少的C ++解释器 [英] Why are there so few C++ interpreters

查看:83
本文介绍了为什么这么少的C ++解释器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我个人只知道1个C ++解释器,它由Root(CINT,在CERN开发)使用。它让我想知道为什么这么少,而且显而易见的答案是C ++是一种非常复杂的解析语言。没有一个心智正常的人会从头开始编写一个C ++解析器...



但是,作为编译器的一部分有C ++解析器,其中一些是开源的。在我看来,有可能解释在运行中解析器发出的汇编代码。这就像一个JIT编译器,它发出字节码以供虚拟机解释。想到的一个问题是使用不同的源文件,否则会导致需要链接的多个目标文件。这确实是一个限制,但如果你问我,这不是一个非常严重的限制。



尽管如此,似乎没有人这样做,这通常意味着它不是看起来很简单(不是说我的想法很简单,但仍然如此)。我想知道我的想法会出现什么问题......有人关心评论吗?

I personally know of only 1 C++ interpreter, which is used by Root (CINT, developed at CERN). It made me wonder why there are so few, and the obvious answer is that C++ is a very complex language to parse. No one in their right mind would bother writing a C++ parser from scratch...

However, there are C++ parsers are out there as part of compilers, some of which are open source. It occurred to me that it might be possible to interpret the assembly code that is emitted by the parser on the go. This would be like a JIT compiler that emits bytecode to be interpreted by a virtual machine. One problem that comes to mind is the use of different source-files which would otherwise lead to several object files that need to be linked. This is indeed a limitation, but not a very serious one if you ask me.

Still, it appears that no one has done this, which normally means that it isn't as easy as it seems (not that my idea would be trivial, but still). I was wondering what the problems with my idea would be... Anyone care to comment?

推荐答案

请参阅bling的问题评论(关于C ++的好主意/ CLI)和我自己。



事实是:CINT不是C ++解释器。 CINT不是C ++解释器。这里有明确说明:

http: //en.wikipedia.org/wiki/CINT [ ^ ]。



该语言是基于C和C ++的简化语言。



参见: http://root.cern.ch/drupal/content/cling [ ^ ]。



如何关于上面引用的维基百科文章中提到的一个替代方案,Ch?这不完全是C ++解释器,它是一些特殊语言的解释器:

http: //en.wikipedia.org/wiki/Ch_%28computer_programming%29 [ ^ ],

http://www.softintegration.com/ [ ^ ]。



还有别的吗? 派克,也只是基于C和C ++(维基百科甚至说受到影响):

http://en.wikipedia.org/wiki/Pike_%28programming_language%29 [ ^ ],

http:// pike。 lysator.liu.se/ [ ^ ]。



对于真正的C ++语言,我有一些人认为它不适合翻译;这个话题太复杂了,无法在快速问题&解答。我不能在这里证明这一点并且不是百分百肯定,倾向于认为可以证明。如果有人证明我错了,我会很惊讶。



-SA
Please see comments to the question, by bling (good idea about C++/CLI), and myself.

The fact is: CINT is not a C++ interpreter. CINT is not a C++ interpreter. This is clearly stated here:
http://en.wikipedia.org/wiki/CINT[^].

The language is some simplified language based on C and C++.

See also: http://root.cern.ch/drupal/content/cling[^].

How about one alternative mentioned in the Wikipedia article referenced above, "Ch"? This is not exactly C++ interpreter, this is an interpreter of some special language:
http://en.wikipedia.org/wiki/Ch_%28computer_programming%29[^],
http://www.softintegration.com/[^].

Anything else? "Pike", also only based on C and C++ (Wikipedia even says "influenced by"):
http://en.wikipedia.org/wiki/Pike_%28programming_language%29[^],
http://pike.lysator.liu.se/[^].

As to "real" C++ language, I have some believe that it is not suitable for an interpreter; the topic is just too complex to discuss my considerations in a Quick Questions & Answers. I cannot prove it right here and am not 100% sure, by tend to think it's possible to prove. I would be quite surprised if someone proved me wrong.

—SA


引用:

我个人只知道1个C ++解释器,它由Root(CINT,在CERN开发)使用。它让我想知道为什么这么少,而且显而易见的答案是C ++是一种非常复杂的解析语言。没有一个心智正常的人会从头开始编写C ++解析器......

I personally know of only 1 C++ interpreter, which is used by Root (CINT, developed at CERN). It made me wonder why there are so few, and the obvious answer is that C++ is a very complex language to parse. No one in their right mind would bother writing a C++ parser from scratch...



这里有一个非常重要的问题:你的目标是什么?为什么C / C ++解释器应该是针对该问题的最佳(或至少是一个相当不错的)可用解决方案?顺便说一句,你的目标是什么?和为什么X是最好的解决方案?通常是一个很好的问题,以决定如何浪费生命中重要的时间。这些通常是解决问题和规划时最好的第一个问题。



我们可以深入研究细节原因,但我的答案是C / C ++不切实际基于控制台的解释语言有很多原因,人们通常不喜欢浪费时间去实现不实用的工具(好吧,也许是那些有很多时间玩乐和学习的人,和/或可能不能决定实现这样的解释器是否会因实际原因而被广泛使用。)



BTW,使用动态类型变量实现动态语言(如python)的解释器与使用C / C ++相比,动态链接函数更容易/更简单,更不容易出错。为简单的动态语言编写整个解析器,编译器,解释器非常简单快捷。解释器本身并不一定非常高效,解释器通常只用于组合高级逻辑。如果某些内容对性能至关重要,那么您可以将其编写为解释器的本机模块,并将其绑定到动态解释语言。在我看来,你并没有真正考虑过C / C ++解释器带来的问题。我至少可以写一本关于他们的小说。以下是最有趣的内容:



C / C ++需要前向声明。在实用的解释语言中,没有前向声明,也没有单独的声明/定义。但这只是一个更严重的问题的一小部分:C / C ++被用作解释语言是不切实际的冗长。这是一组涉及语言设计问题和作为解释语言的实际可用性问题的问题。在python中,我可以轻松定义一个调用不存在的Y函数的X函数,并且我可以在以后随时定义这个Y函数。然后我可以执行X.稍后如果我想我可以完全改变Y的定义(可能使用一些新的默认初始化参数以向后兼容先前的定义)并且X的另一次执行立即使用新的Y定义。我可以执行X,即使它调用了尚未定义的Z函数,如果执行带有实际输入参数的X实际上没有进入调用Z的分支,这也不是问题。 C ++解释器如果我更改了许多以前定义的函数(例如内联函数)使用的非常基本的模板(例如:动态数组)的定义会发生什么?如何使用新的内联函数找出要在解释器中重新编译的代码块?如果使用新定义重新编译其中一些函数失败会发生什么?使用正确的语言与运行时绑定只有你没有像这样的严重问题...在非动态解释器中处理这样的场景将是一个巨大的问题,这些只是两个简单/基本问题,这是只是冰山一角。我已经编程了十多年的C / C ++,但我不想在翻译中使用它。




There is a very important question here: What is your goal and why would a C/C++ interpreter be the best (or at least a reasonably good) available solution for that problem? BTW, the "What is your goal?" and "Why is X the best solution?" are generally good questions to decide how to waste important timeslices from your life. These are generally the best first questions in case of problem solving and planning.

We could delve into the details why, but my answer is that C/C++ is impractical as a console based interpreted language for many reasons and people usually don't like wasting time on implementing tools that are not practical (well, maybe people who have a lot of time to have fun and learn, and/or maybe people who can't decide whether implementing such an interpreter wouldn't be widely used for practical reasons).

BTW, implementing an interpreter for a dynamic language (like python) with dynamically typed variables and "dynamically linked functions" is much easier/simpler and less error prone than doing the same with C/C++. Writing the whole parser, compiler, interpreter for a simple dynamic language is quite easy and quick. The interpreter itself doesn't have to be very performant, an interpreter is usually used only to put together the high level logic. If something is performance critical then you can write it as a native module for your interpreter and binding it to the dynamically interpreted language. In my opinion you haven't really thought over the problems that arise with C/C++ interpreters. I could write at least a novel about them. Here are the most interesting ones that are huge enough:

C/C++ requires forward declarations. In a practical interpreted language there are no forward declarations and there are no separated declarations/definitions. But this is just a tiny part of a more serious problem: C/C++ is impractically verbose to be used as an interpreted language. This is a set of problems that involve both language design problems and practical usability problems as an interpreted language. In python I can easily define an X function that calls a nonexisting Y function and I am allowed to define this Y function anytime later. Then I can execute X. Later if I want I can completely change the definition of Y (maybe with some new default-initialized parameters to be backward compatible with the previous definition) and another execution of X immediately uses the new Y definition. I can execute X even if it calls a Z function that haven't yet been defined and this isn't a problem if the execution of X with the actual input parameters doesn't actually run into the branch that would call Z. In a C++ interpreter what happens if I change the definition of a very basic template (eg: dynamic array) that is used by a lot of previously defined functions (for example as inlined functions)? How do you find out what codeblocks to recompile inside your interpreter in order to use the new inline functions? What happens if the recompilation of some of these functions fail with the new definition? With the correct language with runtime binding only you don't have serious problems like this... Dealing with such scenarios in a non-dynamic interpreter would be a huge problem, and these were just two "simple/basic" problems, this is only the tip of the iceberg. I've been programming C/C++ for more than a decade but I don't want to use it in an interpreter for sure.

Quote:

但是,有些C ++解析器作为编译器的一部分存在,其中一些是开源的。在我看来,有可能解释在运行中解析器发出的汇编代码。这就像一个JIT编译器,它发出字节码以供虚拟机解释。想到的一个问题是使用不同的源文件,否则会导致需要链接的多个目标文件。这确实是一个限制,但如果你问我,这不是一个非常严重的限制。

However, there are C++ parsers are out there as part of compilers, some of which are open source. It occurred to me that it might be possible to interpret the assembly code that is emitted by the parser on the go. This would be like a JIT compiler that emits bytecode to be interpreted by a virtual machine. One problem that comes to mind is the use of different source-files which would otherwise lead to several object files that need to be linked. This is indeed a limitation, but not a very serious one if you ask me.



我开始写一个答案,但它变得太长而且复杂,因为它分析了你的问题沿着许多不同的交叉区域。相反,我在这里写下我的一些结论。



嗯,首先你应该回答我在前一段中发布的问题。从你的问题我想也许你的目标只是简单地用最少的工作投入一个C ++解释器 - 我假设这是因为你想重用现有编译器中的东西(编译单元,目标文件)真的对我有意义。我的问题在于,当人们不得不做一些他们不喜欢的事情时,人们会做投入最少的工作。另一方面,如果他们为了娱乐作为一种兴趣或具有特定目的而做某事,那么他们通常不介意投入工作。根据需求的不同,需要完全不同的解决方案,如果是C / C ++解释器,所有解决方案似乎都涉及很多工作。所以最后你还是应该至少回答你的目标是什么?问题。



根据我们讨论的编译器和编译器设置,目标文件可能包含其他内容而不是您期望的内容。目标文件不是标准化的,即使是相同的编译器也可以通过一些设置(如LTCG)将完全无用的垃圾放入目标文件中。在我看来,不是解析目标文件,而是编写一个发布对你有用的东西的后端更实用。


I started to write an answer but it became too long and complex as it analyzed your problem along many different cross-sections. Instead I write here just some of my conclusions.

Well, first you should answer the questions I've posted in the previous paragraph. From your question I think maybe your goal is simply making A C++ interpreter with the least work invested - I assume this because you want to reuse stuff (compilation units, object files) from existing compilers that don't really make sense to me. My problem with this is that people do something with "least work invested" when they have to do something they don't like. On the other hand if they do something just for fun as a hobby or with a specific purpose then they usually don't mind investing work. Depending on what are the requirements completely different solutions are needed and in case of a C/C++ interpreter all solutions seems to involve a lot of work. So finally you should still answer at least the "What is your goal?" question.

Depending on which compiler and which compiler settings are we talking about object files might contain something else than what you expect. Object files are not standardized and even the same compiler can put completely useless garbage into the object files with some settings (like LTCG). In my opinion instead of parsing object files it is more practical to write a backend that emits something useful for you.


我的推测理由:似乎没有人比efford有需要了去做吧。即你可以在你的花园里建造一座艾菲尔铁塔,假设你拥有空间,材料,人员,足够好的地面等等,你可以为自己的乐趣做到这一点。 ;-)



从C到C ++的区别如C ++标准所述:

My speculative reason: There seems no one have had the need compared to the efford to do it. I.e. you might be able to build an Eiffel Tower in your garden, assuming you have the space, the material, the people, the good enough ground, etc. and you can do it for your own pleasure. ;-)

The difference from C to C++ is as stated in the C++ standard:
除了提供的设施外通过C,C ++提供了额外的数据类型,类,模板,异常,命名空间,运算符重载,函数名重载,引用,免费商店管理运算符和其他库设施。
In addition to the facilities provided by C, C++ provides additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities.



如果去对于C ++ 11,您可以添加lambda表达式和其他几个部分,所有这些都主要是语法糖,因为它们抽象的东西主要与解析器相关,也可以通过其他方式完成(如果不是单调乏味)。



解析上述功能后的运行时项结果是什么?
- 其他数据类型:一些更内置的字符/数字类型

- 类:扩展实例函数,带参数

- 类:继承,基类作为派生类的子对象

- 类:特殊的隐式函数调用(ctor,dtor等)

- 类:用于虚函数调用的vtable

- 类:定义的排序(大多数)在类中无关紧要 - 只有名称查找受影响

- 模板:基于类型或常量积分值生成的类或函数

- 例外:额外的控制流程,特别是清理簿记代码

- 名称空间:语法糖(unuique类型,对象,函数定义和调用)

- 重载:语法糖(解析器创建对正确函数的调用)

- 引用:语法糖,导致指针或根本没有运行时代码

- 新/删除:低级别内存malloc / free加ctor / dtor调用

- 库:基于语言特征的项目集合

- lambda表达式:syntactic sugar(隐式仿函数类)

- ...



需要克服令人讨厌的细节问题,但从技术上讲它可以是rega作为一个扩展得很多的C.



所以,如果你有一个C ++前端设法转换成功能相同的C,那么你就达到了CINT的水平。像多个文件和引用库和目标文件这样的问题并不是C ++独有的,但它是所有C *语言的常见事实。那么,你可以重复使用这些语言解释器的这些概念(CINT?)。



但是再次证明这种努力的合理性在很大程度上取决于预期的收益 。



干杯

Andi


If going to C++11, you might add lambda expressions and several other parts, all mainly syntactic sugar in the sense that they abstract something that is mainly parser related and could also be done (if not tedious) by other means.

What results as runtime items from parsing the above features are
- additional data types: some more built-in char/numeric types
- class: extended instance functions with this parameter
- class: inheritance with base class as sub object of a derived class
- class: special implicit function calls (ctor, dtor, etc.)
- class: vtable for virtual function calls
- class: ordering of definitions (mostly) do not matter in classes - only name lookup is affected
- templates: generated classes or functions based on type or constant integral values
- exceptions: additional control flow and especially cleanup-bookkeeping code
- namespaces: "syntactic sugar" (the unuique types, objects, fucntions get defined and called)
- overloading: "syntactic sugar" (the parser creates calls to the correct functions)
- references: "syntactic sugar", results in pointers or no runtime code at all
- new/delete: low level memory malloc/free plus ctor/dtor calls
- libraries: collection of items that base on language features
- lambda expression: "syntactic sugar" (implicit functor class)
- ...

There are nasty detail problems to overcome, but technically it can be regarded as a much extended C.

So, if you have a C++ frontend that manages to translate into functionally equivalent C, then you arrived at the level of CINT. Problems like multiple files and referencing libraries and object files is not unique to C++ but is a common fact with all C* languages. So, you can re-use these concepts of the interpreter of those languages (CINT?).

But again, justifying the effort depends very much on the prospective "gain".

Cheers
Andi


这篇关于为什么这么少的C ++解释器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆