Java 递归下降解析

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

我在寻找一些关于我的任务的建议/帮助。因为这是一门课,我没有要求任何人帮我写出答案,但我确实需要帮助我编写实际的代码

问题是:

考虑以下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  
使用类中描述的技术实现递归下降 识别此语言中字符串的分析器。输入应来自 应将名为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;