私は、オフサイドの解析を使用する文法を使用しています (iow: ブロック区切り文字としてのタブ)。文法はインデント スタックを使用してネストされたブロックを追跡し、EOF が検出されたときに適切な終了トークンでブロックをラップしようとします。
std::stack<int> indent_stack;
int indent_size;
%x indent
%s normal
%s wrap
%%
<wrap>[ ] {
if(indent_stack.top() > 0)
{
indent_stack.pop();
if(indent_stack.top() > 0) unput(' ');
return DEDENT;
}
else
yyterminate();
}
<<EOF>> {
if(indent_stack.top() > 0)
{
BEGIN(wrap);
unput(' ');
}
else
yyterminate();
}
<indent>[\t] {indent_size++;}
<indent>[\n] {indent_size = 0;}
<indent>. {
unput(*yytext);
if(indent_size > indent_stack.top())
{
indent_stack.push(indent_size);
yytext[0] = '\0';
return INDENT;
}
else if(indent_size < indent_stack.top())
{
indent_stack.pop();
yytext[0] = '\0';
return DEDENT;
}
else
{
BEGIN(normal);
}
}
/* And so begin <normal> rules. */
一見すると、この文法は入力ファイルを字句解析するときに機能するように見えyyin = fopen(...)
ます: .
ただし、入力文字列を lex しようとするとstate = yy_scan_string(...)
、 への最初の呼び出しがyylex
エラーでクラッシュしますflex scanner push-back overflow
。