[英]Distribution of NOT token in bison
給定一個用C ++編寫的if條件(僅條件部分)的輸入,我想根據De Morgan的法律分發“ nots”。 問題是,根據我的規則,當我找到符號“!”時,遞歸不允許我立即獲取括號內的表達式,然后可以進行分發。 讓我用一個例子來解釋:
輸入: (!(a&&(b&&!(c&&d))))
輸出(在找到每個令牌的時間。): c AND d ) ( b AND NOT b ) ( a AND ) ( ) ( NOT
輸出由於遞歸而無序,但是在這種情況下,我如何應用德摩根定律?對於這種輸入,我想獲得:
(!(a&&(b&&!(c&&d))))->(!a&&!(b&&!(c&&d)))->(!a&&b&&(c||d))
注意,每次我發現一個!
令牌,立即用於下一個括號中。 如果我得到(!a&&b)
,則只有當我發現它時,才不必使用它!
和(
作為下一個符號。
因此,問題是:我無法分發!
下一組條件中的令牌,因為我使所有令牌混亂。
這有可能嗎?如何定義規則呢?
main.cpp:
#include <iostream>
#include <string>
#include "lex.yy.c"
using namespace std;
typedef yy_buffer_state *YY_BUFFER_STATE;
extern int yyparse();
extern YY_BUFFER_STATE yy_scan_buffer(char *, size_t);
int main(int argc, char** argv) {
char condition[] = "(!(a&&(b&&!(c&&d)))) \0\0";
yy_scan_buffer(condition, sizeof(condition));
yyparse();
return 0;
}
掃描儀:
%option noyywrap
%{
#include <iostream>
#include "parser.tab.c"
using namespace std;
%}
%%
[a-zA-Z0-9<>=]+ {
yylval = strdup(yytext);
return SYMBOL;
}
"&&" {
return AND;
}
"||" {
return OR;
}
"!" {
return NOT;
}
[ \0\0] {
return END;
}
"(" {
return LEFT_PAR;
}
")" {
return RIGHT_PAR;
}
%%
bison.y:
%{
#include <iostream>
#include <string>
using namespace std;
int yylex(void);
void yyerror(char *);
#define YYSTYPE string
%}
%token LEFT_PAR
RIGHT_PAR
SYMBOL
END
NOT
%left
AND
OR
%start input
%%
input:
| input terms
;
terms:
LEFT_PAR terms close_terms {
cout << " ( ";
}
| LEFT_PAR condition close_terms {
cout << " ( ";
}
| LEFT_PAR NOT condition close_terms {
cout << " ( NOT ";
}
| LEFT_PAR NOT terms close_terms {
cout << " ( NOT ";
}
;
close_terms:
RIGHT_PAR {
cout << " ) ";
}
;
binary_condition:
terms AND terms {
cout << " AND ";
}
| SYMBOL AND terms {
cout << $1 << " AND ";
}
| SYMBOL AND NOT terms {
cout << $1 << " AND NOT " << $3;
}
| terms AND SYMBOL {
cout << " AND " << $3;
}
| SYMBOL AND SYMBOL {
cout << $1 << " AND " << $3;
}
| SYMBOL AND NOT SYMBOL {
cout << $1 << " AND NOT " << $4;
}
| terms OR terms {
cout << " OR ";
}
| SYMBOL OR terms {
cout << $1 << " OR ";
}
| SYMBOL OR NOT terms {
cout << $1 << " OR NOT ";
}
| terms OR SYMBOL {
cout << " OR " << $3;
}
| SYMBOL OR SYMBOL {
cout << $1 << " OR " << $3;
}
| SYMBOL OR NOT SYMBOL {
cout << $1 << " OR NOT " << $4;
}
;
condition:
SYMBOL {
cout << $1;
}
| binary_condition
| binary_condition AND condition
| binary_condition OR condition
;
%%
void yyerror(char *s) {
}
謝謝!
通常,最合理的做法是使您要解析的語法盡可能簡單,然后將要進行的任何轉換都視為解析樹上的轉換,而不是嘗試以某種方式更改語法。 在您的情況下,您有一個非常混亂的語法-進行了AND
和OR
右遞歸並且優先級相等(盡管%left
聲明無效,因為它沒有沖突可以解決。)
因此,您從簡單的表達式語法開始:
%left '|'
%left '&' /* & and | are left recursive, with & having higher precedence */
%%
input: /* empty */ | input expr '\n' ;
expr: SYMBOL | '(' expr ')' | '!' expr | expr '&' expr | expr '|' expr
然后,添加規則以構建表達式樹數據結構並對其進行轉換:
input: /* empty */ | input expr '\n' { PrintExpr(ConvertToNormalForm($2)); }
expr: SYMBOL { $$ = CreateSymbolNode($1); }
| '(' expr ')' { $$ = $2; }
| '!' expr { $$ = CreateUnaryNode('!', $2); }
| expr '&' expr { $$ = CreateBinaryNode('&', $1, $3); }
| expr '|' expr { $$ = CreateBinaryNode('|', $1, $3); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.