C# 标记化后的良好解析方法

C# 标记化后的良好解析方法,c#,parsing,token,interpreter,C#,Parsing,Token,Interpreter,我写了一个程序,在其中我读取一个字符串或文件并标记它。 示例字符串: “int w=sad&&s | a | d++!==>=第一个好方法是为每件事命名,如“操作”、“操作数”、“文字”、“声明”等 然后创建一个函数,该函数可以从您的令牌流中读取每个令牌流,并在适当的情况下调用其他令牌流。例如,如果您有: operation: <operand> <operator> <operand> operator: + | - operand: <number&

我写了一个程序,在其中我读取一个字符串或文件并标记它。 示例字符串:
“int w=sad&&s | a | d++!==<>>=第一个好方法是为每件事命名,如“操作”、“操作数”、“文字”、“声明”等

然后创建一个函数,该函数可以从您的令牌流中读取每个令牌流,并在适当的情况下调用其他令牌流。例如,如果您有:

operation: <operand> <operator> <operand>
operator: + | -
operand: <number> | <string>
当然,有些函数可能需要检查下一个令牌来决定调用哪个其他函数,或者甚至需要提前查看几个令牌

这通常称为“递归下降”解析器

每个函数都返回一个表示操作的对象,并将其参数挂起。这基本上是一个树结构,然后可以递归遍历(“深度优先”)

最简单的方法是给出您定义的不同对象类型或操作和值方法,如asString()或asInt(),然后执行以下操作:

int Operation::asInt()
{
   int a = operand[0].asInt()
   int b = operand[1].asInt()
   return a + b;
}
已经是正确类型的对象(如IntOperand类)将只返回其值:

int IntOperand::asInt()
{
    return self.numericValue
}
或者随便什么。类型不正确的对象要么产生错误,而不是返回值,要么自行转换。因此,无论表达式有多复杂,最终都会得到一个int或string之类的结果

要运行程序,现在可以向最底层的对象询问其值

int Operation::asInt()
{
   int a = operand[0].asInt()
   int b = operand[1].asInt()
   return a + b;
}
int IntOperand::asInt()
{
    return self.numericValue
}