C++ 正确接受bisonc+中的括号+;

C++ 正确接受bisonc+中的括号+;,c++,flex-lexer,bisonc++,C++,Flex Lexer,Bisonc++,我尝试使用bisonc++ 这些规则是: expression -> OPEN_BRACKET expression CLOSE_BRACKET expression -> expression operator expression operator -> PLUS operator -> MINUS 如果我试图运行编译后的代码,我会在这一行得到一个错误: (a+b)-(c+d) 应用第一条规则,最左边和最右边的括号是打开的括号和关闭的括号。剩下的表达式是:a+b

我尝试使用
bisonc++

这些规则是:

expression -> OPEN_BRACKET expression CLOSE_BRACKET
expression -> expression operator expression

operator -> PLUS
operator -> MINUS
如果我试图运行编译后的代码,我会在这一行得到一个错误:

(a+b)-(c+d)
应用第一条规则,最左边和最右边的括号是
打开的括号
关闭的括号
。剩下的
表达式是:
a+b)-(c+d

如何防止这种行为?是否可以计算开括号和闭括号


编辑

表达式语法:

expression:
    OPEN_BRACKET expression CLOSE_BRACKET
    {
        //
    }        
| operator
    {
        //
    }        
| VARIABLE
    {
        //
    }

;


operator:
    expression PLUS expression
    {
        //
    }

| expression MINUS expression
    {
        //
    }

;

Edit2

雷克瑟

CHAR  [a-z]
WS    [ \t\n]

%%

{CHAR}+     return Parser::VARIABLE;

"+"         return Parser::PLUS;
"-"         return Parser::MINUS;

"("         return Parser::OPEN_BRACKET;
")"         return Parser::CLOSE_BRACKET;

这不是正常的表达式语法。请尝试正常的表达式语法

expression
    : term
    | expression '+' term
    | expression '-' term
    ;
term
    : factor
    | term '*' factor
    | term '/' factor
    | term '%' factor
    ;
factor
    : primary
    | '-' factor // unary minus
    | primary '^' factor // exponentiation, right-associative
    ;
primary
    : identifier
    | literal
    | '(' expression ')'
    ;
还请注意上面的缩进和对齐方法,对于单个特殊字符,您只需从lexer返回
yytext[0]
:您不需要特殊的标记名,没有它们更容易阅读:

CHAR [a-zA-Z]
DIGIT [0-9]
WHITESPACE [ \t\r\n]
%%
{CHAR}+       { return Parser::VARIABLE; }
{DIGIT}+      { return Parser::LITERAL; }
{WHITESPACE}+ ;
.             { return yytext[0]; }

这不是正常的表达式语法。请尝试正常的表达式语法

expression
    : term
    | expression '+' term
    | expression '-' term
    ;
term
    : factor
    | term '*' factor
    | term '/' factor
    | term '%' factor
    ;
factor
    : primary
    | '-' factor // unary minus
    | primary '^' factor // exponentiation, right-associative
    ;
primary
    : identifier
    | literal
    | '(' expression ')'
    ;
还请注意上面的缩进和对齐方法,对于单个特殊字符,您只需从lexer返回
yytext[0]
:您不需要特殊的标记名,没有它们更容易阅读:

CHAR [a-zA-Z]
DIGIT [0-9]
WHITESPACE [ \t\r\n]
%%
{CHAR}+       { return Parser::VARIABLE; }
{DIGIT}+      { return Parser::LITERAL; }
{WHITESPACE}+ ;
.             { return yytext[0]; }

您的运算符规则看起来不太好

试着做以下实验:

expression:
    OPEN_BRACKET expression CLOSE_BRACKET
    {
        //
    }

|

    expression operator expression
    {
        //
    }

|

    VARIABLE
    {
        //
    }

;


operator:
    PLUS
    {
        //
    }

|

    MINUS
    {
        //
    }
;

正如您的伪代码实际表明的那样…

您的运算符规则看起来不太好

试着做以下实验:

expression:
    OPEN_BRACKET expression CLOSE_BRACKET
    {
        //
    }

|

    expression operator expression
    {
        //
    }

|

    VARIABLE
    {
        //
    }

;


operator:
    PLUS
    {
        //
    }

|

    MINUS
    {
        //
    }
;

正如你的伪代码所暗示的那样…

它仍然不是一个正常的表达式语法。不要重新发明轮子。我不想重新发明轮子。你为什么这么认为?这是我第一次使用
bisonc
flex
你重新发明轮子,因为你没有使用正常的表达式语法。相反,你在写你自己从头开始。查一下。看看C表达式语法,然后把它删减。它仍然不是一个正常的表达式语法。不要重新发明轮子。我不想重新发明轮子。你为什么这么认为?这是我第一次使用
bisonc
flex
你重新发明轮子,因为你不是使用普通表达式语法。相反,你是在从头开始编写自己的语法。查找它。例如,看看C表达式语法,并将其删减。谢谢。但问题在于括号。我打赌运算符规则定义导致了内部循环,它吸收了每个标记…使用运算符规则,我得到了一个shift/reduce冲突谢谢。但问题在于括号。我打赌运算符规则定义导致了内部循环,它吸收了每个令牌…使用运算符规则,我得到了移位/减少冲突,但这只是相关部分。这是您第一次想到的,您错了。您应该提供有,但这只是相关部分。这是你第一次想到的,你错了。你应该提供一个展示问题的最小但完整的例子。