解析语句并向其添加括号

Parsing a statement and Adding Paranthesis to them

我正在尝试解析逻辑 BNF 语句,并尝试对它们应用括号。

例如: 我正在尝试将语句 a=>b<=>c&d 解析为 ((a) =>(b))<=>((c)&(d)),以及类似的语句。

面临的问题: 有些语句工作正常,有些则不然。上面提供的示例不起作用,解决方案打印为 ((c)&(d))<=>((c)&(d)) 第二个 expr 似乎覆盖了第一个。

有效的条件: 而像 a<=>b 和 a|(b&c) 这样的其他简单示例则工作正常。

我想我在我的代码中犯了一些我无法弄清楚的基本错误。

这是我的代码

lex 文件

letters [a-zA-Z]
identifier {letters}+
operator (?:<=>|=>|\||&|!)
separator [\(\)]    

%%
{identifier} {
    yylval.s = strdup(yytext);
    return IDENTIFIER; }
{operator} { return *yytext; }
{separator} { return *yytext; }
[\n] { return *yytext; }
%%

yacc 文件

%start program
%union  {char* s;}
%type <s> program expr IDENTIFIER
%token IDENTIFIER
%left '<=>'
%left '=>'
%left '|' 
%left '&'
%right '!'
%left '(' ')'

%%
program : expr '\n'     
          { 
            cout<<$$;
            exit(0);
          }
     ;
    
expr : IDENTIFIER  {  
        cout<<" Atom ";
        cout<<<<endl;
        string s1 = string();
        cout<<$$<<endl;
        
    }
     | expr '<=>' expr   {
        cout<<"Inside <=>\n";
        string s1 = string(); 
        string s2 = string(); 
        string s3 = "(" + s1 +")" +"<=>"+"(" + s2 +")";
        $$ = (char *    )s3.c_str();
        cout<<s3<<endl;
     }
     | expr '=>' expr   {
        cout<<"Inside =>\n";
        string s1 = string();
        string s2 = string(); 
        string s3 = "(" + s1 +")" +"=>"+"(" + s2 +")";
        $$ = (char *)s3.c_str();
        cout<<$$<<endl;
     }
     | expr '|' expr    { 
 
        cout<<"Inside |\n";
        string s1 = string();
        string s2 = string(); 
        string s3 = "(" + s1 +")" +"|"+"(" + s2 +")";
        $$ = (char *)s3.c_str();
        cout<<$$<<endl;
     }
     | expr '&' expr    {

        cout<<"Inside &\n";
        string s1 = string();
        string s2 = string(); 
        string s3 = "(" + s1 +")" +"&"+"(" + s2 +")";
        $$ = (char *)s3.c_str();
        cout<<$$<<endl;
     }
     | '!' expr {      

        cout<<"Inside !\n"; 
        string s1 = string();
        cout<<s1<<endl;
        string s2 = "!" + s1;
        $$ = (char *)s2.c_str();
        cout<<$$<<endl;
     }
     | '(' expr ')'         {  $$ = ; cout<<"INSIDE BRACKETS"; }
     ;
%%


请让我知道我所犯的错误。

谢谢

您遇到的基本问题是您将 string::c_str() 返回的指针保存在 yacc 值堆栈中,但是在操作完成并且 string 对象被销毁后,该指针不再存在有效。

要解决此问题,您需要根本不使用 std::string,或者将 %union 更改为 { std::string *s; }(而不是 char *)。在任何一种情况下,您都会遇到内存泄漏问题。如果您使用 Linux,前者非常简单。你的行为会变成这样:

     | expr '<=>' expr   {
        cout<<"Inside <=>\n";
        asprintf(&$$, "(%s)<=>(%s)", , );
        cout<<$$<<endl;
        free();
        free();
     }

对于后者,操作看起来像:

     | expr '<=>' expr   {
        cout<<"Inside <=>\n";
        $$ = new string("(" + * +")" +"<=>"+"(" + * +")");
        cout<<$$<<endl;
        delete ;
        delete ;
     }