我正在从头开始用C#语言编写一个简单的解析器/解释器(没有第三方库)。它编译为字节码,然后我有运行字节码的类。我快要结束了。我刚刚实现了while
和for
循环,并且正在if
| else if
| else
块上工作。
就目前而言,我的解析器要求所有这些结构都使用花括号。我想使其更像C,并且当块仅包含一个语句时,花括号是可选的。这给我带来了麻烦。
if (condition)
{
// Make curly braces optional when there is just one statement here
}
问题是跟踪状态。解析器如何知道没有大括号的块何时结束。一种方法是检查每个语句后是否有一个没有大括号有效的块。但是,将有很多不同的情况构成一个语句,因此这些检查将需要在许多地方进行。对我来说有点脆弱。
我只是想知道是否有人这样做并且知道在没有大括号的情况下跟踪代码块何时结束的任何技巧。
答案 0 :(得分:4)
您需要查看recursive descent parser。它使创建解析器变得容易得多。假设您的语法如下:
statement
: 'if' paren_expr ['{'] statement ['}']
paren_expr
: '(' expr ')'
然后使用递归下降可以执行以下操作:
public void Statement()
{
if(curToken == Token.If)
{
Eat(Token.If); // Eat is convenience method that moves token pointer on
if(curToken == Token.LParen)
{
Eat(Token.LParen)
ParenExpr();
Eat(Token.RParen);
}
if(curToken == Token.LBrace) // this will signify a block of statements
{
Eat(Token.LBrace);
while(curToken != Token.RBrace)
Statement();
Eat(Token.RBrace);
}
else
Statement();
}
}
public void ParenExpr()
{
// do other token checks
}
对所有非终端设备执行此操作,可以轻松构建AST,并由此生成字节码。