Java 递归下降解析
我在寻找一些关于我的任务的建议/帮助。因为这是一门课,我没有要求任何人帮我写出答案,但我确实需要帮助我编写实际的代码 问题是: 考虑以下BNF语法:Java 递归下降解析,java,c++,parsing,recursion,Java,C++,Parsing,Recursion,我在寻找一些关于我的任务的建议/帮助。因为这是一门课,我没有要求任何人帮我写出答案,但我确实需要帮助我编写实际的代码 问题是: 考虑以下BNF语法: A -> I = E E -> T + E | T - E | T T -> F * T | F / T | F F -> P ^ F | P P -> I | L | (E) I -> a | b | ... | y | z L -> 0 | 1 | ... | 8 | 9
A -> I = E
E -> T + E | T - E | T
T -> F * T | F / T | F
F -> P ^ F | P
P -> I | L | (E)
I -> a | b | ... | y | z
L -> 0 | 1 | ... | 8 | 9
使用类中描述的技术实现递归下降
识别此语言中字符串的分析器。输入应来自
应将名为input.dat和output的文件发送到控制台。一
示例会话可能如下所示:
从文件读取的字符串:a=a+b-c*d
字符串“a=a+b-c*d
”在
语言。从文件读取的字符串:a=a**b++c
字符串
“a=a**b++c
”不在该语言中
你必须在java和C++中实现这个项目!启动位置 如果不包含两种语言的解决方案,则最多, 获得一半学分。简化你不必处理的事情 解析字符串时的空白,即“
”和类似字符
此语言中的非法字符
使用不同语法的正确相关示例:
// * <assign> => <id> = <expr>
// * <id> => a | b | c
// * <expr> => <lit> + <lit> | <lit> - <lit>
// * <lit> => 0 | ... | 9 | (<expr>)
#include <iostream>
using std::cout;
using std::endl;
bool assign(void);
bool id(void);
bool expr(void);
bool lit(void);
char *c;
int main(int argc, char *argv[]) {
c = argc == 2 ? argv[1] : (char *)"";
if (assign() && *c == '\0') {
cout << "The string \"" << argv[1] << "\" is in the language." << endl;
}
else {
cout << "The string \"" << argv[1] << "\" is not in the language." << endl;
}
return 0;
}
bool assign(void) {
if (id()) {
if (*c == '=') {
++c;
if (expr()) {
return true;
}
}
}
return false;
}
bool id(void) {
if (*c >= 'a' && *c <= 'c') {
++c;
return true;
}
return false;
}
bool expr(void) {
if (lit()) {
if (*c == '+' || *c == '-') {
++c;
if (lit()) {
return true;
}
}
}
return false;
}
bool lit(void) {
if (*c >= '0' && *c <= '9') {
++c;
return true;
}
else {
if (*c == '(') {
++c;
if (expr()) {
if (*c == ')') {
++c;
return true;
}
}
}
}
return false;
}
//*=>=
//*=>a | b | c
// * => + | -
// * => 0 | ... | 9 | ()
#包括
使用std::cout;
使用std::endl;
布尔赋值(无效);
bool-id(void);
bool expr(无效);
bool-lit(void);
char*c;
int main(int argc,char*argv[]){
c=argc==2?argv[1]:(字符*)“”;
如果(赋值()&&*c=='\0'){
我想你在检测诸如
E = T + E | T - E | T
当您查找T()
失败时,请尝试再次查找T()
。
您在大多数其他函数中也犯了这个错误
E()
的正确实现是(在Chris comment之后更新):
让我们练习一个例子:“a=(3)”
A()
->I()
在调用p()
后返回true->c='='=''''=''
->E()
在解析3
时返回true,调用p()
后再次调用E()
,现在c='
所以我们需要在E()中返回true
否则,如果我们在这里返回false,解析将在P()中停止。
我希望它不会太混乱,但在这里很难表达。最好是将解析树写在一张纸上,使其可视化
再次更新:在T()
和F()中有类似的情况
那么…您在哪一位遇到了问题?假设我们没有机会实际运行您的代码。哪些输入有效?哪些输入失败?它们是如何失败的?那么,当前的问题是什么?问题是没有任何字符串显示为语言中的有效字符串。不幸的是,即使是像a=b这样的简单字符串也有问题运行几乎所有的生产规则,这样我就不会指出哪里出了问题。这很好,但你的实际问题是什么?程序是否没有达到你期望的效果,是否崩溃,是否编译…?你应该问一个新问题-因为读取输入是一个不同的问题,与你的任务无关原始问题。看看这里关于如何提问的内容。对于“a=(3)”之类的输入,这仍然会失败——对于FOLLOW(E)中的任何前瞻,都需要在T之后返回true,而不仅仅是EOF,还不如对+/-以外的任何东西都返回true。我有点明白你们两人在说什么。但我仍然感到困惑。我的印象是,我真的不能使用字符串的结尾作为验证,只有在确认a()之后,才返回true已返回true。我如何进行前瞻以及follow和eof是什么?我确实看到了重复检查的问题之一,正如您所说的,如果if-else-if与两个if具有相同的条件语句,则没有任何意义。@Bob:您的前瞻是*c,follow(E)是可能位于合法E之后的字符集。因为您在匹配a()后在顶层检查EOF('\0'),您不需要在其他任何地方检查它,但这样做并没有什么坏处。@Bob:另外,在您的P规则中,您在匹配I或L后错误地递增了c——I和L例程已经递增了,所以P中的额外一个正在跳过第二个字符
E = T + E | T - E | T
if (T())
{
if (c == '+' || c == '-')
{
++c;
return E();
}
return true;
}
return false;