我想先说这是我第三年编程语言课的家庭作业,我正在寻求一些帮助。我的作业内容如下:
截止日期:2013 年 2 月 22 日晚上 11:55
提交:请将以下内容上传到 CMS。
1. 源代码
2. 程序执行的屏幕截图,包括您使用的输入文件使用您喜欢的任何编程语言编写递归下降解析器,解析由以下 EBNF 描述生成的语言。您的解析器应该检测输入程序是否有任何语法错误。它不必指定错误的内容和位置。
<program> begin <stmt_list> end
<stmt_list> <stmt> {;<stmt_list>}
<stmt> <assign_stmt> | <while_stmt>
<assign_stmt> <var> = <expr>
<var> identifier (An identifier is a string that begins with a letter followed by 0 or more letters and digits)
<expr> <var> { (+|-) <var>}
<while_stmt> while (<logic_expr>) <stmt>
<logic_expr> ® <var> (< | >) <var> (Assume that logic expressions have only less than or greater than operators)
看起来很有趣的符号只是指向右边的箭头。
我现在的问题比编程更合乎逻辑:在我的第一次尝试中,我读入了整个输入程序,将其保存为一个字符串,然后解析该字符串并将每个符号转换为终端、expr 或具有你。
我最终发现这种方式行不通,因为,A:我不认为它是 RDP,B:许多非终端是由超过 1 个语句组成的。
我放弃了这种方法,并决定在我浪费更多时间编程之前,我会把所有东西都伪掉。我的新想法是为每个非终端符号创建 1 个方法,然后逐个符号解析输入字符串,希望在这些方法之间。这种方法似乎是合乎逻辑的,但是当我开始编写伪代码时,我对我需要做什么感到非常迷茫和困惑。 我将如何完成这段代码?
以下是 RDP 的一些伪代码:
intputString;
public void parseProgram (Symbol.typeIsProgram) {
if getNextSymbol == "begin" {
if (intputString.substring (inputString.length()-3,
inputString.length()) == "end") {
Symbol stmt_lsit = new Symbol (intputString)
parseStmt_list(stmt_list);
} else {
Out "error, prog must end with end"
}
} else {
Out "error, prog must begin with begin"
}
}
public void parseStmt_list (Stmbol.typeIsStmt_list) {
symbol = getNextSymbol;
if (Symbol.typeIsVar) {
parseVar(symbol)
} else if (Symbol.typeIsWhile) {
// weve only capture if the first word return is a while, we dont have the whole while statement yet
ParseWhile_stmt(symbol)
} else { }
}
public void parseStmt () { }
public void parseAssign_stmt () { }
public void parseVar () { }
public void parseExpr () { }
public void parseWhile_stmt () { }
public void parseLogic_expr () { }
public Symbol getNextSymbol() {
//returns the next symbol in input string and removes it from the input string
}
仅供参考,我的解析器的示例输入程序将是。
begin
total = var1 + var2;
while (var1 < var2)
while ( var3 > var4)
var2 = var2 - var1
end