我正在嘗試決議邏輯 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<<$1<<endl;
string s1 = string($1);
cout<<$$<<endl;
}
| expr '<=>' expr {
cout<<"Inside <=>\n";
string s1 = string($1);
string s2 = string($3);
string s3 = "(" s1 ")" "<=>" "(" s2 ")";
$$ = (char * )s3.c_str();
cout<<s3<<endl;
}
| expr '=>' expr {
cout<<"Inside =>\n";
string s1 = string($1);
string s2 = string($3);
string s3 = "(" s1 ")" "=>" "(" s2 ")";
$$ = (char *)s3.c_str();
cout<<$$<<endl;
}
| expr '|' expr {
cout<<"Inside |\n";
string s1 = string($1);
string s2 = string($3);
string s3 = "(" s1 ")" "|" "(" s2 ")";
$$ = (char *)s3.c_str();
cout<<$$<<endl;
}
| expr '&' expr {
cout<<"Inside &\n";
string s1 = string($1);
string s2 = string($3);
string s3 = "(" s1 ")" "&" "(" s2 ")";
$$ = (char *)s3.c_str();
cout<<$$<<endl;
}
| '!' expr {
cout<<"Inside !\n";
string s1 = string($2);
cout<<s1<<endl;
string s2 = "!" s1;
$$ = (char *)s2.c_str();
cout<<$$<<endl;
}
| '(' expr ')' { $$ = $2; cout<<"INSIDE BRACKETS"; }
;
%%
請讓我知道我所犯的錯誤。
謝謝
uj5u.com熱心網友回復:
您遇到的基本問題是string::c_str()將 yacc回傳的指標保存在yacc 值堆疊上,但是在操作完成且string物件被銷毀后,該指標不再有效。
要解決此問題,您需要根本不使用std::string,或者將您更改%union為{ std::string *s; }(而不是char *)。無論哪種情況,您都會遇到記憶體泄漏問題。如果您使用的是 Linux,前者很容易。你的行為會變成這樣:
| expr '<=>' expr {
cout<<"Inside <=>\n";
asprintf(&$$, "(%s)<=>(%s)", $1, $3);
cout<<$$<<endl;
free($1);
free($3);
}
對于后者,操作如下所示:
| expr '<=>' expr {
cout<<"Inside <=>\n";
$$ = new string("(" *$1 ")" "<=>" "(" *$2 ")");
cout<<$$<<endl;
delete $1;
delete $3;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/321983.html
標籤:解析 flex-lexer 雅克 莱克斯 野牛
