解析树不起作用

Parse tree doesn't work

本文关键字:不起作用      更新时间:2023-10-16

我想建立一个简单的解析树/但它不工作。我认为strlen返回了错误的结果。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
int min(int a ,int b){ return (a>b)?b:a;}
class Node
{
    Node* left;
    Node* right;
    char operation;
public:
    float res;
    Node(char* str)
    {
        char* ch = NULL;
        ch = strrchr2(str);
        if (ch==NULL)
        {
            if(str[0]=='(')
            {
                str = &str[1]; 
                int k = strlen(str);
                char *tmp = new char[k-1];
                strncpy(tmp,str,k-1);
                ch = strrchr2(tmp);
                div(tmp,ch);
            }
            else
                res = atof(str);                
        }
        else
        {
            div(str,ch);
        }
    }
    void div(char* str,char* ch)
    {
            //getting opertion
            strncpy(&operation,ch,1);
            //getting position of operation
            int pos = strlen(str)-strlen(ch);
            //right node creation
            ch = &ch[1];
            right = new Node(ch);
            //left node creation
            char* tmp = new char[pos];
            strncpy(tmp,str,pos);
            left = new Node(tmp);
            //applying opertion to to node's results
            switch( operation )
            {
                case '/':this->res = left->res/right->res;break;
                case '*':this->res = left->res*right->res;break;
                case '+':this->res = left->res+right->res;break;
                case '-':this->res = left->res-right->res;break;
                default:break;
            };
    }
    char* strrchr2(char* s)
    {
        char* str = new char[strlen(s)];
        strcpy(str,s);
        int i = search(str);
        if(i==-1) return NULL;
            else
        if(str[i]=='+' || str[i]=='-') return &str[i];
            else if (str[i] == '*' || str[i]=='/')
            {
                char c = str[i+1];
                if(i+1<strlen(str)-1 && search(&c)!=-1) return strrchr2(&c);
                else return &str[i];
            }
    }
    int search(char* str)
    {
        int cnt1 = 0;
        int cnt2 = 0;
        for(int i=0;i<strlen(str);i++)
        {
            if (str[i]=='(') cnt1++;
            else if (str[i]==')') cnt2++;
            if (cnt1!=0)
            {
               if(cnt1==cnt2)
               {
                  int m = strlen(str);
                  return ((i+1)!=m?i+1:-1);
               }
            }
            else
            {
                if (str[i]=='-' || str[i]=='+' || str[i]=='*' || str[i]=='/') return i;
            }
        }
        char* ch = NULL;
        ch = strchr(str,'-');
        if(ch==NULL) ch = strchr(str,'+');
        if(ch==NULL) ch = strchr(str,'*');
        if(ch==NULL) ch = strchr(str,'/');
        if(ch==NULL)return -1;
        else return strlen(str)-strlen(ch);
    }
};
int main()
{
    char* expr = "(1/2)-(1/2)";
    Node* n = new Node(expr);
    printf("%s = %.3f",expr,n->res);

    _getch();
}

看起来你是在用类做C而不是c++。尝试使用std::string代替char *。这样使用strlen就不会有任何麻烦了(如果strlen真的有问题的话),因为string有一个size()函数,它保证工作得很好。最重要的是,您将能够使用您试图在那里重新编码的许多功能。

关于字符串的更多信息:http://www.cplusplus.com/reference/string/string/

M。Dijsktra还创建了一个算法来解析数学表达式并输出AST(抽象语法树)。它将允许你处理更复杂的表达式。它被称为"分流场算法"。这是在维基百科上:http://en.wikipedia.org/wiki/Shunting-yard_algorithm

我想你可能想知道已经做了什么。:)

你应该这样做。

你要确保你使用的是一个好的IDE和一个集成的调试器。能够逐步遍历代码并查看变量是绝对重要的。专家也可以在没有这些奢侈的东西的情况下调试代码,但这需要非常多的专业知识。

所以你需要一个调试器。如果你使用的是Windows,你可以免费获得Visual Studio 2010 Express。或者您可能已经有了一个调试器。

接下来你要做的是逐行遍历代码,并确保每一步都能准确地完成它应该做的事情。这很乏味,但就是这样。

"This code doesn't work"并不能解决问题。StackOverflow上的人可以为您做的唯一一件事(除了发现基于运气的明显错误)就是将代码加载到他们自己的调试器中并为您逐步执行。但是你真的需要学会自己去做。

注:库函数和编译器基本上总是工作的。如果你认为你在其中发现了一个bug,那么你几乎肯定没有。如果您仍然这样认为,请尝试用几行代码重现该bug。如果真的有一个bug,那么它几乎总是会被简化为5行程序。如果你不能把它减少到一个非常短的程序,那么它几乎可以肯定是你的代码中的一个bug,如果它不是,那么你就知道没有询问StackOverflow。