インデントで定義されたPythonのブロックを再作成しようとすると、私はこの時点で右に遭遇しました。BisonパーサーでFlexの開始条件を処理する際に間違ったトークンがあります
レクサー/スキャナを別々に試してみると、私が作った開始条件を使って、期待通りの結果を返してくれます。しかし、それを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;
}
を返すレクサー他のすべての他の他の他の。
後者の場合、予期しない結果」 テスト を入力
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;
}
を返すパーサ "(前と同じ)は、"インデントインデント他の他のインデントインデント "を返します。予想された結果は上記と同じですが。
Bisonパーサーは、開始条件を尊重していないかのように、間違ったトークンを受け取っているようです。先読みのためにパーサが開始条件を混乱させていることを読んだことがありますが、問題がこの中にあるかどうか、またどのように対処するかはわかりません。あなたはルールセクションのパターンのない
BEGIN(INDENT)
を持っているので
これは非常に奇妙な方法です。私は '^ [\ t] BEGIN INDENT;'を持ち、その状態では起動しません。 – EJP