【问题标题】:Creating a parser for a simple pseudocode language?为简单的伪代码语言创建解析器?
【发布时间】:2012-04-15 00:26:00
【问题描述】:

我想用 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)转换为波兰符号,然后存储在堆栈中。在每次迭代中,在弹出操作数时,我可以替换每个变量的值。但这是否足够高效?

提前感谢您的任何建议。

【问题讨论】:

标签: java parsing


【解决方案1】:

虽然我认为为这样的语言构建解析器很棒,但这样做比看起来要困难得多。解析是一个经过充分研究的问题,您可以使用许多优秀的算法,但它们很难手动实现。虽然您可以将转换为 RPN 之类的技巧用于解析表达式等较小的示例,但构建完整的编程语言需要一组更复杂的技巧。

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

希望这会有所帮助!

【讨论】:

  • 已经实现了一些“非常难以手工实现”的算法(例如,LL、L(AL)R 和 GLR,我想说的是实现它们并将它们用于单个项目的努力恕我直言,通常不如使用较弱的方法构建完整的解析器。同意您应该尽可能获得现成的工具,仅仅是因为它的工作量较少,而不是因为它非常难。
  • 谢谢!我会去看看他们两个,但你能选择其中一个吗? :P 考虑到我的示例代码,我会在 GPL 下发布我的代码,占用空间更小等。呵呵,我肯定会做一个解析器,但可能改天。
  • @VinayakGarg- 我没有太多经验,但 ANTLR 拥有广泛的社区基础。可能值得探索。
【解决方案2】:

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

如果您不确定,请以您可以获得的最强大的解析器生成器的形式使用矫枉过正。

【讨论】:

  • 您的链接内容丰富,谢谢。然后是元编译器,然后是网站。一切看起来都很棒,我很想在下学期做这件事。但由于目前我的时间和经验不足,我会去矫枉过正!
【解决方案3】:

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

但是,使用 StringTokenizer 是做错的标志,因为 StringTokenizer 已经是一个简单的解析器。

解析器通常读取一个字符并根据该字符的值更改其状态。

只是一个简单的解析器,一个“b”使后面的字符“大写”,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 ++;
 }

【讨论】:

  • 好吧,您使用术语 SIMPLE 解析器作为“常规语言的解析器”,您的示例显示了一个非常简单的常规语言解析器。在最初的问题中,语言被认为是简单的,因为没有词汇歧义。然而,语言本身是严格上下文无关的。因此,无法使用您在此处实现的简单有限状态自动机来解析它。
  • 在 while 循环结束之前缺少 'pos' 的增量 :)
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多