]> vcs.slashdirt.org Git - sw/tic2json.git/commitdiff

vcs.slashdirt.org Git - sw/tic2json.git/commitdiff

git git / sw / tic2json.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (initial)
initial commit fully working on sample data
2021年8月13日 13:26:20 +0000 (15:26 +0200)
2021年8月15日 11:21:02 +0000 (13:21 +0200)
tic.l [new file with mode: 0644] patch | blob
tic.y [new file with mode: 0644] patch | blob

diff --git a/tic.l b/tic.l
new file mode 100644 (file)
index 0000000..971e61c
--- /dev/null
+++ b/tic.l
@@ -0,0 +1,164 @@
+/*
+// tic.l
+//
+//
+// (C) 2021 Thibaut VARENE
+// License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html
+*/
+
+/* noyywrap disables automatic rewinding for the next file to parse. Since we
+ always parse only a single string, there's no need to do any wraps. And
+ using yywrap requires linking with -lfl, which provides the default yywrap
+ implementation that always returns 1 anyway. */
+%option noyywrap
+
+/* nounput simplifies the lexer, by removing support for putting a character
+ back into the input stream. We never use such capability anyway. */
+%option nounput
+
+/* batch means that we'll never use the generated lexer interactively. */
+%option batch
+
+/* Enables debug mode. To see the debug messages, one needs to also set
+ yy_flex_debug to 1, then the debug messages will be printed on stderr. */
+%option nodebug
+
+HORODATE [ EeHh][0-9]{12}
+DATAC [\x20-\x7e]
+CHKSUM [\x20-\x5f]
+/* séparateur de champ. \x20 en mode historique: DATAC ne contient alors pas 0x20 */
+SEP \x09
+
+%{
+ #include "tic.tab.h"
+
+ static uint8_t checksum;
+
+ static void crc_calc(void)
+ {
+ for (size_t i = 0; i<yyleng; i++)
+ checksum += (uint8_t)yytext[i];
+ }
+%}
+
+%%
+
+ /* balises */
+\x02 { return TOK_STX; }
+\x03 { return TOK_ETX; }
+\x0a { checksum=0; return FIELD_START; }
+{SEP} { checksum += (uint8_t)*yytext; return TOK_SEP; }
+{CHKSUM}\x0d {
+ checksum = (checksum & 0x3f) + 0x20;
+ if (checksum == (uint8_t)yytext[0]) return FIELD_OK;
+ else return FIELD_KO;
+ }
+
+
+ /* etiquettes - mode historique mono - non supporté */
+ /*
+ADCO
+OPTARIF
+ISOUSC
+BASE
+HCHC
+HCHP
+EJPHN
+EJPHPM
+BBRHCJB
+BBRHPJB
+BBRHCJW
+BBRHPJW
+BBRHCJR
+BBRHPJR
+PEJP
+PTEC
+DEMAIN
+IINST
+ADPS
+IMAX
+PAPP
+HHPHC
+MOTDETAT
+ */
+
+ /* etiquettes - mode standard */
+ADSC { crc_calc(); yylval.text = strdup(yytext); return ET_ADSC; }
+VTIC { crc_calc(); yylval.text = strdup(yytext); return ET_VTIC; }
+DATE { crc_calc(); yylval.text = strdup(yytext); return ET_DATE; }
+NGTF { crc_calc(); yylval.text = strdup(yytext); return ET_NGTF; }
+LTARF { crc_calc(); yylval.text = strdup(yytext); return ET_LTARF; }
+EAST { crc_calc(); yylval.text = strdup(yytext); return ET_EAST; }
+EASF01 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF01; }
+EASF02 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF02; }
+EASF03 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF03; }
+EASF04 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF04; }
+EASF05 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF05; }
+EASF06 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF06; }
+EASF07 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF07; }
+EASF08 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF08; }
+EASF09 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF09; }
+EASF10 { crc_calc(); yylval.text = strdup(yytext); return ET_EASF10; }
+EASD01 { crc_calc(); yylval.text = strdup(yytext); return ET_EASD01; }
+EASD02 { crc_calc(); yylval.text = strdup(yytext); return ET_EASD02; }
+EASD03 { crc_calc(); yylval.text = strdup(yytext); return ET_EASD03; }
+EASD04 { crc_calc(); yylval.text = strdup(yytext); return ET_EASD04; }
+EAIT { crc_calc(); yylval.text = strdup(yytext); return ET_EAIT; }
+ERQ1 { crc_calc(); yylval.text = strdup(yytext); return ET_ERQ1; }
+ERQ2 { crc_calc(); yylval.text = strdup(yytext); return ET_ERQ2; }
+ERQ3 { crc_calc(); yylval.text = strdup(yytext); return ET_ERQ3; }
+ERQ4 { crc_calc(); yylval.text = strdup(yytext); return ET_ERQ4; }
+IRMS1 { crc_calc(); yylval.text = strdup(yytext); return ET_IRMS1; }
+IRMS2 { crc_calc(); yylval.text = strdup(yytext); return ET_IRMS2; }
+IRMS3 { crc_calc(); yylval.text = strdup(yytext); return ET_IRMS3; }
+URMS1 { crc_calc(); yylval.text = strdup(yytext); return ET_URMS1; }
+URMS2 { crc_calc(); yylval.text = strdup(yytext); return ET_URMS2; }
+URMS3 { crc_calc(); yylval.text = strdup(yytext); return ET_URMS3; }
+PREF { crc_calc(); yylval.text = strdup(yytext); return ET_PREF; }
+PCOUP { crc_calc(); yylval.text = strdup(yytext); return ET_PCOUP; }
+SINSTS { crc_calc(); yylval.text = strdup(yytext); return ET_SINSTS; }
+SINSTS1 { crc_calc(); yylval.text = strdup(yytext); return ET_SINSTS1; }
+SINSTS2 { crc_calc(); yylval.text = strdup(yytext); return ET_SINSTS2; }
+SINSTS3 { crc_calc(); yylval.text = strdup(yytext); return ET_SINSTS3; }
+SMAXSN { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN; }
+SMAXSN1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN1; }
+SMAXSN2 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN2; }
+SMAXSN3 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN3; }
+SMAXSN-1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSNM1; }
+SMAXSN1-1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN1M1; }
+SMAXSN2-1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN2M1; }
+SMAXSN3-1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXSN3M1; }
+SINSTI { crc_calc(); yylval.text = strdup(yytext); return ET_SINSTI; }
+SMAXIN { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXIN; }
+SMAXIN-1 { crc_calc(); yylval.text = strdup(yytext); return ET_SMAXINM1; }
+CCASN { crc_calc(); yylval.text = strdup(yytext); return ET_CCASN; }
+CCASN-1 { crc_calc(); yylval.text = strdup(yytext); return ET_CCASNM1; }
+CCAIN { crc_calc(); yylval.text = strdup(yytext); return ET_CCAIN; }
+CCAIN-1 { crc_calc(); yylval.text = strdup(yytext); return ET_CCAINM1; }
+UMOY1 { crc_calc(); yylval.text = strdup(yytext); return ET_UMOY1; }
+UMOY2 { crc_calc(); yylval.text = strdup(yytext); return ET_UMOY2; }
+UMOY3 { crc_calc(); yylval.text = strdup(yytext); return ET_UMOY3; }
+STGE { crc_calc(); yylval.text = strdup(yytext); return ET_STGE; }
+DPM1 { crc_calc(); yylval.text = strdup(yytext); return ET_DPM1; }
+FPM1 { crc_calc(); yylval.text = strdup(yytext); return ET_FPM1; }
+DPM2 { crc_calc(); yylval.text = strdup(yytext); return ET_DPM2; }
+FPM2 { crc_calc(); yylval.text = strdup(yytext); return ET_FPM2; }
+DPM3 { crc_calc(); yylval.text = strdup(yytext); return ET_DPM3; }
+FPM3 { crc_calc(); yylval.text = strdup(yytext); return ET_FPM3; }
+MSG1 { crc_calc(); yylval.text = strdup(yytext); return ET_MSG1; }
+MSG2 { crc_calc(); yylval.text = strdup(yytext); return ET_MSG2; }
+PRM { crc_calc(); yylval.text = strdup(yytext); return ET_PRM; }
+RELAIS { crc_calc(); yylval.text = strdup(yytext); return ET_RELAIS; }
+NTARF { crc_calc(); yylval.text = strdup(yytext); return ET_NTARF; }
+NJOURF { crc_calc(); yylval.text = strdup(yytext); return ET_NJOURF; }
+NJOURF\+1 { crc_calc(); yylval.text = strdup(yytext); return ET_NJOURFP1; }
+PJOURF\+1 { crc_calc(); yylval.text = strdup(yytext); return ET_PJOURFP1; }
+PPOINTE { crc_calc(); yylval.text = strdup(yytext); return ET_PPOINTE; }
+
+{HORODATE} { crc_calc(); yylval.text = strdup(yytext); return TOK_HDATE; }
+{DATAC}+ { crc_calc(); yylval.text = strdup(yytext); return TOK_DATA; }
+
+. { printf("spurious character %c\n", *yytext); return 0; }
+
+<<EOF>> { yyterminate(); }
+%%
diff --git a/tic.y b/tic.y
new file mode 100644 (file)
index 0000000..3654f78
--- /dev/null
+++ b/tic.y
@@ -0,0 +1,224 @@
+//
+// tic.y
+//
+//
+// (C) 2021 Thibaut VARENE
+// License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html
+//
+
+%{
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ int yylex();
+ int yylex_destroy();
+ extern FILE *yyin;
+ void yyerror(const char *);
+
+static int hooked;
+static char fdelim;
+
+struct tic_field {
+ char label[8];
+ char *horodate;
+ char *data;
+};
+
+struct tic_field *make_field(char *label, char *horodate, char *data)
+{
+ struct tic_field *field;
+
+ field = malloc(sizeof(*field));
+ if (!field)
+ return NULL;
+
+ strncpy(field->label, label, sizeof(field->label));
+ free(label);
+ field->horodate = horodate;
+ field->data = data;
+
+ return field;
+}
+
+void free_field(struct tic_field *field)
+{
+ free(field->horodate);
+ free(field->data);
+ free(field);
+}
+
+%}
+
+%union {
+ char *text;
+ struct tic_field *field;
+}
+
+%verbose
+
+%token TOK_STX TOK_ETX TOK_SEP
+%token FIELD_START FIELD_OK FIELD_KO
+
+%token <text> TOK_HDATE TOK_DATA
+
+%token <text> ET_ADSC ET_VTIC ET_DATE ET_NGTF ET_LTARF
+%token <text> ET_EAST ET_EASF01 ET_EASF02 ET_EASF03 ET_EASF04 ET_EASF05 ET_EASF06 ET_EASF07 ET_EASF08 ET_EASF09 ET_EASF10
+%token <text> ET_EASD01 ET_EASD02 ET_EASD03 ET_EASD04 ET_EAIT ET_ERQ1 ET_ERQ2 ET_ERQ3 ET_ERQ4
+%token <text> ET_IRMS1 ET_IRMS2 ET_IRMS3 ET_URMS1 ET_URMS2 ET_URMS3 ET_PREF ET_PCOUP
+%token <text> ET_SINSTS ET_SINSTS1 ET_SINSTS2 ET_SINSTS3 ET_SMAXSN ET_SMAXSN1 ET_SMAXSN2 ET_SMAXSN3
+%token <text> ET_SMAXSNM1 ET_SMAXSN1M1 ET_SMAXSN2M1 ET_SMAXSN3M1 ET_SINSTI ET_SMAXIN ET_SMAXINM1
+%token <text> ET_CCASN ET_CCASNM1 ET_CCAIN ET_CCAINM1 ET_UMOY1 ET_UMOY2 ET_UMOY3 ET_STGE ET_DPM1 ET_FPM1 ET_DPM2 ET_FPM2 ET_DPM3 ET_FPM3
+%token <text> ET_MSG1 ET_MSG2 ET_PRM ET_RELAIS ET_NTARF ET_NJOURF ET_NJOURFP1 ET_PJOURFP1 ET_PPOINTE
+
+%type <text> etiquette_horodate etiquette_nodate
+%type <field> field_horodate field_nodate field
+
+%destructor { free($$); } <text>
+%destructor { free_field($$); } <field>
+%destructor { } <>
+
+%%
+
+frames:
+ frame
+ | frames frame
+;
+
+frame:
+ TOK_STX datasets TOK_ETX
+ {
+ if (!hooked) { hooked=1; printf("[\n["); }
+ else { fdelim=' '; printf ("],\n["); }
+ }
+ | error TOK_ETX { hooked=0; }
+;
+
+datasets:
+ dataset
+ | datasets dataset
+;
+
+dataset:
+ FIELD_START field FIELD_OK
+ {
+ if (!2ドル) YYABORT; // OOM
+ if (hooked) {
+ printf("%c{ \"label\": \"%.8s\", \"data\": \"%s\"", fdelim, 2ドル->label, 2ドル->data ? 2ドル->data : "");
+ if (2ドル->horodate)
+ printf(", \"horodate\": \"%s\"", 2ドル->horodate);
+ printf(" }");
+ fdelim = ',';
+ }
+ free_field(2ドル);
+ }
+ | FIELD_START field FIELD_KO { if (!2ドル) YYABORT; printf("invalid checksum\n"); free_field(2ドル); }
+ | FIELD_START error FIELD_OK
+ | FIELD_START error FIELD_KO
+;
+
+field: field_horodate
+ | field_nodate
+;
+
+field_horodate:
+ etiquette_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_DATA TOK_SEP { $$ = make_field(1,ドル 3,ドル 5ドル); }
+ | etiquette_horodate TOK_SEP TOK_HDATE TOK_SEP TOK_SEP { $$ = make_field(1,ドル 3,ドル NULL); }
+;
+
+field_nodate:
+ etiquette_nodate TOK_SEP TOK_DATA TOK_SEP { $$ = make_field(1,ドル NULL, 3ドル); }
+;
+
+etiquette_horodate:
+ ET_DATE
+ | ET_SMAXSN
+ | ET_SMAXSN1
+ | ET_SMAXSN2
+ | ET_SMAXSN3
+ | ET_SMAXSNM1
+ | ET_SMAXSN1M1
+ | ET_SMAXSN2M1
+ | ET_SMAXSN3M1
+ | ET_SMAXIN
+ | ET_SMAXINM1
+ | ET_CCASN
+ | ET_CCASNM1
+ | ET_CCAIN
+ | ET_CCAINM1
+ | ET_UMOY1
+ | ET_UMOY2
+ | ET_UMOY3
+ | ET_DPM1
+ | ET_FPM1
+ | ET_DPM2
+ | ET_FPM2
+ | ET_DPM3
+ | ET_FPM3
+;
+
+etiquette_nodate:
+ ET_ADSC
+ | ET_VTIC
+ | ET_NGTF
+ | ET_LTARF
+ | ET_EAST
+ | ET_EASF01
+ | ET_EASF02
+ | ET_EASF03
+ | ET_EASF04
+ | ET_EASF05
+ | ET_EASF06
+ | ET_EASF07
+ | ET_EASF08
+ | ET_EASF09
+ | ET_EASF10
+ | ET_EASD01
+ | ET_EASD02
+ | ET_EASD03
+ | ET_EASD04
+ | ET_EAIT
+ | ET_ERQ1
+ | ET_ERQ2
+ | ET_ERQ3
+ | ET_ERQ4
+ | ET_IRMS1
+ | ET_IRMS2
+ | ET_IRMS3
+ | ET_URMS1
+ | ET_URMS2
+ | ET_URMS3
+ | ET_PREF
+ | ET_PCOUP
+ | ET_SINSTS
+ | ET_SINSTS1
+ | ET_SINSTS2
+ | ET_SINSTS3
+ | ET_SINSTI
+ | ET_STGE
+ | ET_MSG1
+ | ET_MSG2
+ | ET_PRM
+ | ET_RELAIS
+ | ET_NTARF
+ | ET_NJOURF
+ | ET_NJOURFP1
+ | ET_PJOURFP1
+ | ET_PPOINTE
+;
+
+
+%%
+
+int main(int argc, char **argv)
+{
+ hooked = 0;
+ fdelim = ' ';
+ yyparse();
+ printf("]\n]\n");
+ yylex_destroy();
+ return 0;
+}
+
+void yyerror(const char * s)
+{
+}
tic2json TIC parser/converter
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /