%{
#include <stdio.h>
#include <glib.h> /* For GString */
#include "../../src/expenses/types.h"
#include "../../src/expenses/csv.h"
/* suppress warning about missing declarations */
int yylex();
int yyparse();
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
%}
%code requires {
#include "../../src/expenses/types.h"
#include "../../src/expenses/csv.h"
/* Parse a string with Flex+Bison instead of a file / stdout */
int grammar_parse_string(const GString *buf);
/* start a SIGALARM routine */
int start_alarm_reminder(unsigned int minutes);
}
%define parse.lac full
%define parse.error verbose
%union {
int res; /* return value of C procedure */
double val; /* For returning numbers. */
BotCommand cmd;
BotReportTimespan tsp;
GString *str;
}
%token <res> TOK_INT
%token <val> TOK_DOUBLE
%token <cmd> TOK_CMD_IN TOK_CMD_OUT TOK_CMD_DEL TOK_CMD_REPORT TOK_CMD_REMINDER
%token <tsp> TOK_TS_DAILY TOK_TS_WEEKLY TOK_TS_MONTHLY TOK_TS_YEARLY
%token <str> TOK_USER /* string for user */
%token <str> TOK_STR /* string for notes */
%type <cmd> update;
%type <val> value;
%type <tsp> ts;
%type <res> msg;
%%
input: /* empty */
| input line
;
line: '\n'
| msg
| error '\n' { yyerrok; }
;
msg: update value TOK_USER TOK_STR
{
int res = write_update_to_csv(bot_get_filename(), $1, $2, $3, $4);
printf("update [%d]: %d %f %s %s\n", res, $1, $2, $3->str, $4->str); $$ = 0;
}
| TOK_CMD_REMINDER TOK_INT
{
int res = start_alarm_reminder($2);
printf("reminder in %d minutes\n", $2); $$ = 0;
}
| TOK_CMD_DEL TOK_INT { printf("delete: %d\n", $2); $$ = 0; }
| TOK_CMD_REPORT ts { printf("report: %d\n", $2); $$ = 0; }
value: TOK_INT { $$ = (double)$1; }
| TOK_DOUBLE
;
update: TOK_CMD_IN
| TOK_CMD_OUT
;
ts: TOK_TS_DAILY
| TOK_TS_WEEKLY
| TOK_TS_MONTHLY
| TOK_TS_YEARLY
;
%%
/* Parse a string with Flex+Bison instead of a file / stdout */
int grammar_parse_string(const GString *buf) {
int res;
yy_scan_string(buf->str);
res = yyparse();
yylex_destroy();
return res;
}
/* start a SIGALARM routine */
int start_alarm_reminder(unsigned int minutes)
{
/* in seconds */
alarm(minutes * 60);
BotReminder *reminder = malloc(sizeof *reminder);
reminder->minutes = minutes;
reminder->from = g_string_new(NULL); /* to be set by the message handler of the bot */
bot_set_last_command(BOT_CMD_REMINDER);
bot_set_last_reminder(reminder);
return 0;
}