【发布时间】:2019-12-16 15:51:07
【问题描述】:
所以我正在制作一种“玩具语言”并使用“玩具编译器”来执行代码。
基本上,我在 C# 中设计所有东西,并简单地说它是如何工作的,只是从源文件中创建标记,循环它们并使用 C# 操作列表设计指令。
我已经尝试向后“解析/编译”所有内容,然后在执行时反转操作列表,考虑到问题的结构,这非常愚蠢。
这里是来自“玩具语言”的部分源代码
printl("Hello, What is your name?")
string Name = inline()
printl("Oh, hello there " + Name)
而我的 C#“玩具编译器”是通过添加操作来完成的,所以
printl("Hello, what is your name?")
将函数内的字符串作为具有值的标记给出以下解析代码:
Actions.Add(new Action(() => Console.WriteLine(CurrentTok.Value)));
虽然在代码的最后一部分中具有多个值,但它只需要一个空对象并通过将值转换为字符串来循环添加所有值,直到当前标记变为')' RightParen 标记。生成一个对象,其中包含使用 ToString() 函数打印的所有值。
对于我有inline() 函数的那个,给出以下
还要记住,我有一个<string, object> 类型的Dictionary 来存储所有变量。
Actions.Add(new Action(() => Variables[Var_name] = Console.ReadLine()));
现在问题出现在解析应该写出该值的最后一行时,因为它已经被“编译”并且变量没有值。 inline() 命令执行后。
该变量不会更新它的值,因为它在一个列表中。
这里是“编译器”代码的简化版本,为了更好地解释问题,请注意。 Current = Tokens[Index]
While(Index < Tokens.Count - 1)
{ // Index a simple int
if(Ignore.Contains(CurrentTok.Type)) // Type = Type of Token
Index++ // if it's a { or a }.. and so on
if(CurrentTok.Type == TokenType.String) // TokenType = enum
{
if(Current.Value == "inline()")
{
Variables[Current.Symbol] = " "; // so it's not undefined
Actions.Add(new Action(() => Variables[Current.Symbol] = Console.ReadLine()
)); // Current.Symbol being the variable name
} else {
Variables[Current.Symbol] = Current.Value;
}
}
if(Current.Type == TokenType.Function) {
if(Current.Symbol == "printl") {
Index++;
if(Current.Type == TokenType.LParen) { // '('
Index++;
object ToPrint = " "; // init an object
While(Current.Type != TokenType.RParen) { // ')'
if(Current.Type == TokenType.Plus)
Index++;
if(Current.Type == TokenType.PrintString) {
// PrintString being a string inside a function
// that has not been declared as an variable.
object ToAdd = Current.Value;
ToPrint += Convert.ToString(ToAdd);
}
if(Current.Type == TokenType.String) {
object ToAdd = GetVar(Current.Symbol);
//GetVar = object that returns the value if the dictionary contains it
ToPrint += Convert.ToString(ToAdd);
}
Index++;
}
Actions.Add(new Action(() => Console.WriteLine(ToPrint)));
} else {
// errors...
}
}
}
index++;
}
从我上面列出的源代码中它可以正常工作,它打印文本Hello, What is your name 并使用 readline 打开输入流。但返回 Oh, heloo there 不带名称。
【问题讨论】:
-
我不明白你为什么不能再次查找
Variables[Var_name]。你想让编译器检查变量是否存在? -
@hugo 你能详细说明一下,你的意思是抬头吗?一切都存储在一个动作列表中,然后在解析完成后,它执行每个动作。给出我所说的问题,因为变量是在没有值的操作中给出的。是的,我有一个函数可以查找变量是否存在,如果它不可用则返回“未定义”
-
创建另一个标记列表'List
'(或HashSet,whatevs),您在编译时更新。在编译期间的任何步骤,您都可以使用它来了解声明是否与此标记匹配。 -
@hugo 现在又一次我不明白这会如何解决?由于所有内容都已在列表中,因此在执行之前的操作以更新它之后,我如何转到该特定索引?有没有办法将事件添加到值分配中?
-
您的问题缺少太多信息...您应该提供实际显示问题的代码。
标签: c#