簡體   English   中英

野牛中NOT標記的分布

[英]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) {

}

謝謝!

通常,最合理的做法是使您要解析的語法盡可能簡單,然后將要進行的任何轉換都視為解析樹上的轉換,而不是嘗試以某種方式更改語法。 在您的情況下,您有一個非常混亂的語法-進行了ANDOR右遞歸並且優先級相等(盡管%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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM