How to implement python style indentation in yacc or bison? -
i have been trying implement python style indentation in bison grammar, insights or ideas implementation nice.
the best way have lexer track indentation level , insert indent/unindent tokens token stream appropriately. here's flex code have that:
%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); }
this code tricky special cases -- example, need ignore blank lines , lines comments, , want ignore indentation within unbalanced parenthesis (which above does).
Comments
Post a Comment