Java 为简单的伪代码语言创建解析器?
我想用Java为类似“伪代码”的语言(保持僵化)制作一个简单的解析器。 一个示例伪代码是——Java 为简单的伪代码语言创建解析器?,java,parsing,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 } } 请注意,上面的代码是严格的,因为一行不能有多个语句,整数以$开头,浮点以#开头
//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)转换为波兰符号,然后存储在堆栈中。在每次迭代中,当弹出操作数时,我可以替换每个变量的值。但这是否足够有效
提前感谢您的建议。尽管我认为您希望为这样的语言构建解析器非常好,但这样做比看起来要困难得多。解析是一个研究得很好的问题,有许多优秀的算法可以使用,但手工实现非常困难。虽然您可以在解析表达式等较小的示例中使用转换为RPN之类的技巧,但构建完整的编程语言需要更复杂的技巧 要解析如此复杂的语言,最好使用解析器生成器,而不是手动编写自己的解析器生成器。这是两个众所周知的工具,可以精确地完成您感兴趣的任务,我强烈建议您使用其中的一个
希望这有帮助 在简单的情况下,手动编写解析器是有意义的 然而,使用StringTokenizer是一个错误的指示器,因为StringTokenizer已经是一个简单的解析器了 解析器通常读取字符并根据该字符的值更改其状态 只是一个简单的解析器,一个“b”使下面的字符“大写”,从e到小写。“”停止
String input=“aDDbcDDeaaef。”;
int pos=0;
int state=0;
while(pos
对于简单语言(这是一个判断调用,如果您没有经验,可能无法正确地进行该调用),通常可以手工编写一个递归下降解析器,这已经足够好了。好消息是
如果您不确定,请以您能获得的最强解析器生成器的形式使用overkill。可能重复实现了一些“极难手动实现”的算法(例如,LL、L(AL)R和GLR,我要说的是,实现它们并将它们用于单个项目IMHO的努力通常比使用较弱的方法构建完整的解析器的努力要少。同意您应该在您可以的地方获得一个现成的工具,只是因为它工作更少,而不是因为它非常困难。谢谢!我将去看看这两个工具,但您能理解吗k其中一个?:P考虑到我的示例代码,我会在GPL下发布我的代码,占用的空间更小等等。呵呵,我肯定会做一个解析器,但可能有一天。@VinayakGarg-我对这两个方面都没有太多经验,但ANTLR有着广泛的社区基础。这可能值得探索。您的链接非常有用,谢谢。t然后是元编译器,然后是网站。这一切看起来都很好,我很想在下学期做。但由于目前我时间和经验不足,我会做得太过火了!好吧,你用术语简单解析器作为“常规语言的解析器”您的示例显示了一个非常简单的常规语言解析器。在最初的问题中,该语言被认为是简单的,因为没有词汇歧义。但是,该语言本身严格与上下文无关。因此,无法使用您在此处实现的简单有限状态自动机对其进行解析。的增量在while循环结束之前缺少pos:)
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 ++;
}