1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* topformflat.l; see License.txt for copyright and terms of use
*
* Scott McPeak <smcpeak@cs.berkeley.edu>
*
* flatten all toplevel forms to single lines.
* very heuristic... */
%{
#include <stdlib.h> // atoi
// emit yytext as-is
void emit();
// debugging diagnostic, emitted when enabled
void diag(char const *str);
// add a newline if nesting <= threshold
void possibleNewline();
// keep track of brace nesting (0 means not inside any pair)
int nesting = 0;
// nesting threshold; when nesting is greater than threshold,
// newlines are suppressed
int threshold = 0;
%}
/* don't try to call yywrap() */
%option noyywrap
/* dsw: don't define yyunput() */
%option nounput
/* start condition for strings */
%x STRING
%x CHARLIT
%%
";" { emit(); possibleNewline(); }
"/\n" { if (nesting <= threshold) { /* end of C comment */
emit();
}
else {
printf("%c", yytext[0]);
}
}
"{" { nesting++;
emit();
possibleNewline(); // so the header is separated from the components
}
"}"(";"?) { nesting--;
emit();
possibleNewline();
}
/* a hash, then some non-newlines. then, possibly, an escaped
* newline followed by more non-newlines (repeat as needed).
* finally, a newline */
"#".*("\\\n".*)*"\n" {
printf("\n"); /* make sure starts on own line */
emit(); /* preprocessor */
}
"\n" { printf(" "); } /* not any above case, eat it*/
"//".*"\n" { emit(); } /* C++ comment */
"\"" { diag("<STR>"); emit(); BEGIN(STRING); } /* start quote */
<STRING>{
"\\"(.|\n) { emit(); } /* escaped character */
"\"" { emit(); diag("</STR>"); BEGIN(INITIAL); } /* close quote */
(.|\n) { emit(); } /* ordinary char */
}
"\'" { diag("<CHAR>"); emit(); BEGIN(CHARLIT); } /* start tick */
<CHARLIT>{
"\\"(.|\n) { emit(); } /* escaped character */
"\'" { emit(); diag("</CHAR>"); BEGIN(INITIAL); } /* close tick */
(.|\n) { emit(); } /* ordinary char */
}
. { emit(); }
%%
void emit()
{
printf("%.*s", yyleng, yytext);
}
void diag(char const *str)
{
//printf("%s", str);
}
void possibleNewline()
{
if (nesting <= threshold) {
printf("\n");
}
}
char *version = "2003.7.14";
int main(int argc, char *argv[])
{
if (isatty(0)) {
printf("topformflat version %s\n", version);
printf("usage: %s [threshold] <input.c >output.c\n", argv[0]);
printf(" The threshold (default: 0) specifies at what nesting level\n"
" of braces will line breaks be allowed (or inserted). By\n"
" starting with 0, you get all top-level forms, one per line\n"
" (roughly). Increasing the threshold leads to finer-grained\n"
" structure on each line. The intent is to use the delta\n"
" minimizer on each level of granularity.\n");
return 0;
}
if (argc >= 2) {
threshold = atoi(argv[1]); // user-specified threshold
}
yyin = stdin;
yylex();
return 0;
}
|