Я использую Flex и Bison для анализа JSON. Вот как выглядит мой Flex:
%%
[ \n\t]+
true { return VAL_TRUE; }
false { return VAL_FALSE; }
null { return VAL_NULL; }
{STRING} { yylval->string = strdup(yytext); return STRING; }
{NUMBER} { yyval->number = atof(yytext); return NUMBER; }
\{ { return OBJ_BEG; }
\} { return OBJ_END; }
: { return SYM_COLON; }
, { return SYM_COMMA; }
%%
И у меня есть такая грамматика в Bison:
%%
START: OBJECT { printf("%s\n", $1); }
;
OBJECT: OBJ_BEG OBJ_END { $$ = "{}\n"; }
| OBJ_BEG MEMBERS OBJ_END {
$$ = ALLOC(2+strlen($2)+2);
sprintf($$,"{ %s }",$2);
}
;
MEMBERS: PAIR { $$ = $1; }
| PAIR SYM_COMMA MEMBERS {
$$ = ALLOC(strlen($1)+2+strlen($3));
sprintf($$,"%s, %s",$1,$3);
}
;
PAIR: STRING SYM_COLON VALUE {
$$ = ALLOC(strlen($1)+2+strlen($3));
sprintf($$,"%s: %s",$1,$3);
}
;
...
VALUE: STRING { $$ = yylval.string; }
| NUMBER { $$ = yylval.number; }
| OBJECT { $$ = $1; }
| ARRAY { $$ = $1; }
| VAL_TRUE { $$ = "true"; }
| VAL_FALSE { $$ = "false"; }
| VAL_NULL { $$ = "null"; }
;
%%
Используя все это, я пытаюсь идентифицировать JSON. Я также форматирую ввод, добавляя запятые, скобки и пробелы.
Но что я застрял, так это то, как сохранить все разрывы строк «\ n» и табуляции «\ n», которые у меня есть во входном JSON, и отправить их непосредственно на выход? Теперь я игнорирую их в «[ 'n\t]+» Flex, а затем добавляю пробелы вручную в некоторых действиях Bison.
Это подход, о котором я думаю:
Я могу определить "\n" и "\t" во Flex и перенаправить их в Bison как SYM_LINEBREAK или SYM_TAB. Но как мне добавить их для вывода в действиях Бизона и куда я могу поместить эти правила/действия?
Вкратце, что мне нужно сделать: добавить пробелы, переносы строк и табуляции для вывода и сохранить разрывы строк и табуляции (но не пробелы), которые были во входном файле.
Заранее спасибо!