为简单的伪代码语言创建解析器?

时间:2012-03-31 16:59:10

标签: java parsing

我想在Java中创建一个简单的解析器,用于语言(保持僵化)的“伪代码”。 示例伪代码是 -

//This is a comment
$x1 = readint
$x2 = readint

$dx = $x2 - $x1
#f = $dx / 2

if ($dx > 0)
{
  loop while(#f > 1)
  {
     print(#f)
     #f = #f / 2
  }
}

请注意,上面的代码是严格的,一行上不能有多个语句,整数以$开头,浮点数以#等开头。

要解析此类代码,首先我可以使用StringTokenizer,然后使用正则表达式来匹配整数变量,浮点变量或关键字。

这种做法好吗?对于循环语句,我如何存储表达式,以便我不必在每次迭代中进行标记化?

我可以考虑将表达式(如#f = #f / 2)转换为抛光表示法,然后将其存储在堆栈中。在每次迭代中,在弹出操作数时,我可以替换每个变量的值。但这足够有效吗?

提前致谢,任何建议。

3 个答案:

答案 0 :(得分:11)

虽然我认为你想为这样的语言构建一个解析器很棒,但这样做比它看起来要困难得多。解析是一个研究得很好的问题,你可以使用许多优秀的算法,但它们很难手工实现。虽然您可以使用转换为RPN等技巧来处理较小的示例(如解析表达式),但构建完整的编程语言需要更复杂的技巧。

要解析这种复杂性的语言,最好使用解析器生成器,而不是手动编写自己的语言。 ANTLRJava CUP是两个众所周知的工具,可以准确地完成您感兴趣的内容,我强烈建议您使用其中一个。

希望这有帮助!

答案 1 :(得分:2)

对于简单语言(这是一个判断调用,如果你没有经验,你可能无法正确地进行该调用),人们通常可以手动编写一个递归下降解析器,并且运行良好。好消息是coding a recursive descent parser is pretty straightforward

如果你不确定,可以使用最强大的解析器生成器的形式使用overkill。

答案 2 :(得分:1)

在简单的情况下手动编写解析器是有意义的。

然而,使用StringTokenizer是做错的一个指标,因为StringTokenizer已经是一个SIMPLE解析器。

解析器通常会读取char并根据该char的值更改其状态。

只是一个简单的解析器,“b”跟随char“大写”,e到小写。 “”停止

 String input = "aDDbcDDeaaef.";

 int pos = 0;

 int state = 0;  
 while (pos < input.length()) {
    char z = input.charAt (pos);
    if (z == '.') break;
    switch (z) {
    case 'b': state = 1; break;
    case 'e': state = 0; break;
    default:
      if (state == 0) {
        System.out.print(Char.toLowerCase(z));
      } else {
        System.out.print(Char.toUpperCase(z));
      }
    }
    pos ++;
 }