如何用C#编写一个简单的类似Logo的解释器?

发布于 2024-12-26 09:44:50 字数 107 浏览 3 评论 0原文

我将如何用 C# 编写一个解释器以及它是如何工作的?

此外,有关普通解释器的任何其他信息 - 即(Python)以及它如何读取 if 语句、计算表达式等工作 - 甚至伪代码将不胜感激。

How would I go about writing an interpreter in C# and how does one work?

Also any other information about normal interpreters - i.e. (Python) and how it reads if statements, calculates expression, etc. work - or even pesudo code would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘曦 2025-01-02 09:44:50

编写解释器不一定是一项艰巨的工作,但它确实需要结构化的方法和强大的编码技能。

首先标记化,列出代码、字符串、关键字、运算符等所有组件的列表。每个组件都占用一个槽,例如:

  1. print
  2. (
  3. "Hello \"world\""
  4. )

这应该不会太难。

现在根据标识符在代码中的位置等进行分类。您应该能够判断它们是函数调用、运算符、变量还是其他什么。

现在进行括号匹配,运行列表,同时更新一堆不匹配的左括号,每当括号匹配时,将其从堆栈中删除并链接匹配的括号,为每个括号提供一个指向另一个的指针。

你的列表必须做成一棵树,现在你可以开始阻止东西,每对括号构成一个块,并且根据语言的不同,其他结构可能构成一个类似括号的块。 (开始-结束语句和类似的语句可以简单地像括号一样对待)。您只需将这样的块制作成列表上的单个元素,其中包含所有子元素的列表。此后,您将为每个运算符优先级遍历树一次,并对这些运算符进行阻塞。

现在,您可以列出所有变量和函数,每个范围一个,并检查是否存在冲突。

对于每个作用域,您都会创建一个有序的变量列表,以便您可以建立一个内存块并确切地知道每个变量的去向。

将变量和函数名称分别替换为内存块位置和函数声明的链接。

现在您可以继续完全编译该程序,或在解释器中运行它。

要运行它,请创建一个调用堆栈列表和一个匹配的范围列表。每当调用函数时,请注意调用堆栈中的返回位置并建立一个匹配的作用域,当调用完成时,会销毁该作用域并返回到返回位置。

正常的语言结构应该很容易处理,每当有一个 if 时,你知道它后面跟着两个块,如果第一个块的计算结果为 false,则跳过第二个块。类似地,一旦您将循环和其他构造视为由固定数量的块组成,并且具有一些决定何时执行其中每个块的简单规则,那么它们就很容易处理。


我现在已经向您提供了结构化方法,但我不能保证实施它的技能。有无数可能的性能调整,而且很多我没有明确告诉如何实施,你必须弄清楚。

Writing an interpreter isn't necessarily a big job, but it does require a structured approach and strong coding skills in general.

First tokenization, make a list of all the components of the code, sting, keywords, operators etc. all take one slot each, like:

  1. print
  2. (
  3. "Hello \"world\""
  4. )

This shouldn't be too hard.

Now do identifier classification, depending on their position in code etc. you should be able to figure if they are function calls, operators, variables or whatever.

Now do bracket matching, run through the list while updating a stack of unmatched opening brackets, whenever a bracket is matched remove it from the stack and link the matching brackets giving each a pointer to the other.

Your list have to be made into a tree, now you can start blocking stuff, every pair of brackets make a block, and depending on language other constructs may constitute a bracket-like block. (begin-end statements and similar can simply be treated like brackets). Such a block you simply make into a single element on the list containing a list of all it's sub-elements. Hereafter you traverse the tree once for each operator precedence level and do blocking for those operators.

Now you can make lists of all variables and functions, one for each scope, and check that there are no collisions.

For each scope you make an ordered list of variables so that you can erect a block of memory and know exactly where each goes.

Replace variable and function names with links to memory block location and function declarations respectively.

Now you could go on to compile the program completely, or run it in an interpreter.

To run it, make a call stack list, and a matching list of scopes. Whenever a function is called note the return position in the call stack and erect a matching scope, when it is finished destroy the scope and return to the return position.

Normal language constructs should be pretty easy to handle, whenever there is an if you know that it is followed by two blocks, if the first block evaluate to false, skip the second. Similarly loops and other constructs are trivial to handle once you consider them as consisting of a fixed number of blocks with some trivial rules dictating when to execute each one of them.


I have now given you the structured approach, the skill to implement it I can't guarantee. There are countless possible performance tweaks, and a lot that I haven't explicitly told how to implement, you'll have to figure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文