#include "parse.h"
-gpointer parse(FILE *input, GList **data, GList **code);
+gpointer parse(FILE *input, const char *name,
+ GList **data, GList **code);
int main(int argc, char **argv)
{
+ const char *name = "stdin";
/* Parse arguments */
char *option_output = NULL;
GOptionEntry entries[] = {
/* Handle input and output */
FILE *input = stdin;
- if (argv[1] && !g_str_equal(input, "-"))
+ if (argv[1] && !g_str_equal(input, "-")) {
+ name = argv[1];
input = fopen(argv[1], "r");
+ }
if (!input)
g_error("invalid input file");
/* Start compiling */
GList *data = NULL;
GList *code = NULL;
- parse(input, &data, &code);
+ parse(input, name, &data, &code);
data = g_list_reverse(data);
code = g_list_reverse(code);
extern FILE *yyin;
int yylex(void);
void yyerror(gpointer node, char const *s);
-static GList *code = NULL;
-static GList *data = NULL;
+extern int yylineno;
+static const char *name;
+static GList *code;
+static GList *data;
%}
%error-verbose
%parse-param {gpointer root};
-%token START END DATA OUT
+%token START END DATA FMT OUT
%%
input : all | all input ;
data : DATA {
static int i = 0;
data = g_list_prepend(data, g_strdup_printf(
+ "#line %d \"%s\"\n"
"static char data%d[] = \"%s\";\n",
- i, g_strescape($1, "")));
+ yylineno, name, i, g_strescape($1, "")));
code = g_list_prepend(code, g_strdup_printf(
+ "#line %d \"%s\"\n"
"fwrite(data%d, sizeof(data%d)-1, 1, stdout);\n",
- i, i));
+ yylineno, name, i, i));
i++;
};
code = g_list_prepend(code, g_strdup_printf("%s\n", $2));
};
-print : START OUT DATA END {
+print : START FMT DATA END {
code = g_list_prepend(code, g_strdup_printf("printf(%s);\n", $3));
};
+print : START OUT DATA END {
+ code = g_list_prepend(code, g_strdup_printf("printf(\"%%s\", %s);\n", $3));
+};
+
%%
-gpointer parse(FILE *input, GList **_data, GList **_code) {
+gpointer parse(FILE *input, const char *_name,
+ GList **_data, GList **_code)
+{
yyin = input;
+ name = _name;
yyparse(NULL);
*_data = data;
*_code = code;
return NULL;
}
-void yyerror(gpointer root, char const *s) {
+void yyerror(gpointer root, char const *s)
+{
g_error("[%s]\n", s);
}
%option noyywrap
%option nounput
%option noinput
+%option yylineno
/* %option nodebug */
START [ \t]*<%
-END [ \t]*%>[ \t]*
+END [ \t]*%>
DATA ([^<\n]|<[^%])*\n*
CODE [ \t\n]([^%\n]|%[^>])*\n*
-%s IN FMT
+%s IN
%%
[[:space:]]*\n { debug("NL [%s]"); }
<INITIAL>{START} { debug("START [%s]"); yylval = g_strdup(yytext); BEGIN(IN); return START; }
<INITIAL>{DATA} { debug("DATA [%s]"); yylval = g_strdup(yytext); return DATA; }
<IN>{END} { debug("END [%s]"); yylval = g_strdup(yytext); BEGIN(INITIAL); return END; }
<IN>= { debug("OUT [%s]"); yylval = g_strdup(yytext); return OUT; }
+<IN>% { debug("FMT [%s]"); yylval = g_strdup(yytext); return FMT; }
<IN>{CODE} { debug("CODE [%s]"); yylval = g_strdup(yytext); return DATA; }
%%