在嘗試重新創建由縮進定義的Python塊時,我在開始時偶然發現了這個問題。處理Flex啓動條件時Bison分析器上的標記錯誤
當我單獨嘗試我的詞法分析器/掃描儀時,它會返回我預期的結果,正確使用我所做的開始條件。但是,當它與Bison解析器耦合時,正確的狀態不會保留,並且我從意外狀態接收到令牌。
對於我來說,預期的行爲是返回一行開始處的製表符/空格的「INDENT」標記,並在找到另一個符號(而不是製表符/空格)後爲每個符號返回「OTHER」標記,直到開始新隊。
第一種情況,詞法分析器歸國預期結果
scanner.l
%{
#include <iostream>
%}
%option noyywrap
%x INDENT
%%
BEGIN(INDENT);
<INDENT>[ \t] { std::cout << "INDENT "; }
<INDENT>.|\n { yyless(0); BEGIN(INITIAL); }
\n { std::cout << std::endl; BEGIN(INDENT); }
. { std::cout << "OTHER "; }
%%
int main(){
yylex();
return 0;
}
進入 「 測試 」(兩個空格之前和 「測試」)之後返回「INDENT INDENT OTHER OTHER OTHER OTHER OTHER OTHER OTHER「。
第二種情況下,解析器返回意想不到的結果
scanner.l
%{
#include <iostream>
#include "parser.h"
%}
%option noyywrap
%x INDENT
%%
BEGIN(INDENT);
<INDENT>[ \t] { return T_INDENT; }
<INDENT>.|\n { yyless(0); BEGIN(INITIAL); }
\n { BEGIN(INDENT); return T_NEWLINE; }
. { return T_OTHER; }
%%
parser.y
%{
#include <iostream>
extern int yylex();
void yyerror(const char *s);
%}
%define parse.error verbose
%token T_INDENT T_OTHER T_NEWLINE
%%
program : program symbol
| %empty
;
symbol : T_INDENT { std::cout << "INDENT "; }
| T_NEWLINE { std::cout << std::endl; }
| T_OTHER { std::cout << "OTHER "; }
;
%%
void yyerror(const char *s){
std::cout << s;
}
int main(){
yyparse();
return 0;
}
進入「 測試 「(與以前相同)返回」INDENT INDENT OTHER OTHER OTHER OTHER INDENT INDENT「。雖然預期的結果與上述相同。
Bison解析器似乎收到錯誤的標記,就好像它不遵守開始條件。我已經閱讀了一些關於解析器由於前瞻行爲而搞亂了開始條件的問題,但我不確定問題出在這個範圍之內,也不知道我會如何解決它。
這是一個非常奇怪的方式來做到這一點。我會''[\ t] BEGIN INDENT;',而不是從那個狀態開始。 – EJP