-1
我一直在試圖在我的野牛語法中實現python樣式縮進,對此實現的一些見解或想法會很好。如何在yacc或bison中實現python風格的縮進?
我一直在試圖在我的野牛語法中實現python樣式縮進,對此實現的一些見解或想法會很好。如何在yacc或bison中實現python風格的縮進?
的最佳方式通常是讓詞法分析器跟蹤縮進層次,並插入縮進/取消縮進適當令牌到令牌流。下面是一些Flex代碼我必須這樣做:
%x LINESTART
%s NORMAL
%{
static std::stack<int> indent;
static int indent_depth(const char *);
%}
%%
<INITIAL>.*|\n { yyless(0); BEGIN(LINESTART); indent.push(0); }
<LINESTART>[ \t]* { int depth = indent_depth(yytext);
if (depth < indent.top()) {
indent.pop();
yyless(0);
return UNINDENT; }
BEGIN(NORMAL);
if (depth > indent.top()) {
indent.push(depth);
return INDENT; } }
<LINESTART>. { yyless(0);
if (indent.top() > 0) {
indent.pop();
return UNINDENT; }
BEGIN(NORMAL); }
<LINESTART><<EOF>> { if (indent.top() > 0) {
indent.pop();
return UNINDENT; }
BEGIN(NORMAL); }
<LINESTART>[ \t]*\n { lineno++; }
<LINESTART>[ \t]*#.*\n { lineno++; }
[[({] { parens++; return *yytext; }
[])}] { if (--parens < 0) parens = 0;
return *yytext; }
\n { lineno++;
if (parens == 0) BEGIN(LINESTART); }
此代碼是特殊情況有點棘手 - 例如,你需要忽略空行和以公正的意見,你可能也想忽略縮進在不平衡的圓括號內(上面這樣做)。