【问题标题】:Accept brackets correctly in bisonc++在 bisoc++ 中正确接受括号
【发布时间】:2016-02-28 20:31:02
【问题描述】:

我尝试使用bisonc++ 编写一个基本的语法检查器

规则是:

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

operator -> PLUS
operator -> MINUS

如果我尝试运行编译后的代码,我会在这一行得到一个错误:

(a+b)-(c+d)

应用第一条规则,最左边和最右边的括号是OPEN_BRACKETCLOSE_BRACKET。剩下的expression是:a+b)-(c+d

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


编辑

表达式语法:

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

;


operator:
    expression PLUS expression
    {
        //
    }

| expression MINUS expression
    {
        //
    }

;

编辑2

词法分析器

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

%%

{CHAR}+     return Parser::VARIABLE;

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

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

【问题讨论】:

  • 有,但这只是相关部分
  • 这是你第一次想到的,你错了。您应该提供一个展示问题的最小但完整的示例。

标签: c++ flex-lexer bisonc++


【解决方案1】:

这不是一个正常的表达式语法。试试普通的。

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 ')'
    ;

还要注意上面的缩进和对齐方法,你只需要从词法分析器中为单个特殊字符返回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]; }

【讨论】:

  • 这仍然不是一个正常的表达式语法。不要重新发明轮子。
  • 我不想重新发明轮子。你为什么这么认为?这是我第一次使用bisoncflex
  • 您在重新发明轮子因为您没有使用正常的表达式语法。 相反,您是从头开始编写自己的。查一下。以 C 表达式语法为例,将其删减。
【解决方案2】:

您的操作员规则看起来不太好。

尝试实验:

expression:
    OPEN_BRACKET expression CLOSE_BRACKET
    {
        //
    }

|

    expression operator expression
    {
        //
    }

|

    VARIABLE
    {
        //
    }

;


operator:
    PLUS
    {
        //
    }

|

    MINUS
    {
        //
    }
;

正如你的伪代码实际上所暗示的那样......

【讨论】:

  • 谢谢。但问题在于括号
  • 我打赌运营商规则定义导致了内部循环,它吸收了每个令牌......
  • 根据您的操作员规则,我遇到了移位/减少冲突
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多