Parsing 奇野牛句法分析

Parsing 奇野牛句法分析,parsing,bison,flex-lexer,Parsing,Bison,Flex Lexer,作为借口,我知道解析结构的格式很奇怪,老师希望它大致是这种格式 我正在使用flex和bison使一个简单的“计算器”解析器形成一个赋值,但在使用模数时,我得到了奇怪或不寻常的结果。它似乎适用于所有其他操作 Input: "10 % 5" Output: " % 10" Input: "101 % 12" Output: " % 101" Input: "2^(-1 + 15/5) - 3*(4-1) + (-6)" Output: "-11" //Correct 野牛的相关

作为借口,我知道解析结构的格式很奇怪,老师希望它大致是这种格式

我正在使用flex和bison使一个简单的“计算器”解析器形成一个赋值,但在使用模数时,我得到了奇怪或不寻常的结果。它似乎适用于所有其他操作

Input:   "10 % 5"
Output:  "  % 10"
Input:    "101 % 12"
Output:   "  % 101"
Input: "2^(-1 + 15/5) - 3*(4-1) + (-6)"
Output: "-11" //Correct
野牛的相关部分

command : pexpri    {printf("%d\n", $1); return;}
        ;

pexpri  : '-' expri '+' termi   {$$ = -$2 + $4;} /* Super glued on unary, also reduce conflict, TODO: find bug */
        | '-' expri '-' termi   {$$ = -$2 - $4;}
        | '-' expri             {$$ = -$2;}
        | expri                 {$$ = $1;}
        ;
expri   : expri '+' termi   {$$ = $1 + $3;} /* Addition subtraction level operations*/
        | expri '-' termi   {$$ = $1 - $3;}
        | termi             {$$ = $1;}
        ;
termi   : termi '*' factori     {$$ = $1 * $3;} /* Multiplication division level operations*/
        | termi '/' factori     {$$ = $1 / $3;}
        | termi '%' factori     {$$ = $1 % $3;}
        | factori               {$$ = $1;}
        ;
factori : factori '^' parti {$$ = pow($1, $3);} /* Exponentiation level operations */
        | parti             {$$ = $1;}
        ;
parti   : '(' pexpri ')'        {$$ = $2;} /* Parentheses handling or terminal, also adds even more reduction errors.... */
        | INTEGER
        ;
相关章节tokenizer.l

0           { /* To avoid useless trailing zeros. */
                yylval.iVal = atoi(yytext);
                return INTEGER;
            }
[1-9][0-9]* {
                yylval.iVal = atoi(yytext);
                return INTEGER;
            }
[-()^\+\*/]         {return *yytext;}
主函数本质上只是yyparse的包装器

我不明白它是如何或为什么在输出中打印模数符号的,因为整个代码中唯一的打印是在命令部分。我知道代码不是最好的(事实上,它很糟糕),但任何洞察都是非常值得赞赏的

另外,如果有人能帮我弄清楚如何以更优雅的方式处理一元否定(希望不会破坏太多),我也将不胜感激。(我不能只使用%precidence或%left)我当前设置它的方式不明确,并且会导致减少错误。

如果仔细查看

[-()^\+\*/]         {return *yytext;}
您会注意到它不会匹配%。最可能的结果是(f)lex的默认回退规则将适用。该规则匹配任何单个字符,并使用
ECHO
将匹配的标记复制到输出流

在我看来,空白字符也可能违反默认规则。应该明确地忽略它们

顺便说一下,在字符类中不需要反斜杠转义正则表达式运算符,因为它们在该上下文中没有特殊意义。因此,正确且易于阅读的规则是

[-+*/%^()]         {return *yytext;}
但是,我强烈建议使用回退规则,而不是列出所有可能的单字符标记。如果回退规则处理无效的单字符令牌,则解析器将通过标记错误来响应

[[:space:]]+      { /* Ignore whitespace*/ }
0|[1-9][0-9]*     { yylval.iVal = atoi(yytext); return INTEGER; }
.                 { return *yytext; /* Fallback rule */ }
默认的回退规则在解析中很少有用,我发现添加它很有用

%option nodefault

到我的flex prolog,如果需要回退规则,这将导致flex生成错误消息。

此外,您的两个问题彼此没有关系。所以更喜欢只问一个问题的帖子;这使得通过搜索更容易发现问题和答案。天哪,我是个笨蛋。我简直不敢相信我在为一件技术上甚至不在我任务范围内的事情而挣扎。非常感谢。@siech0:但是您了解了(f)lex的默认回退规则,如果要使用(f)lex,这是一个非常重要的问题。:-)