%{ #include #include #include #include "stb_sb.h" #include "hmmlib.h" typedef struct { int line; HMML_Annotation* annos; HMML_VideoMetaData meta; HMML_Annotation an; HMML_Reference ref; HMML_Error error; char** attr; int mnext; bool first; } HMML_ParseState; #define HMML_ERR(fmt, ...) \ do { \ asprintf(&yyextra->error.message, fmt, ##__VA_ARGS__);\ yyextra->error.line = yyextra->line;\ return 1;\ } while(0) #define V_(x) &yyextra->meta.x #define R_(x) &yyextra->ref.x #define M_(x, state) do { HMML_Marker m = { HMML_ ## x }; sb_push(yyextra->an.markers, m); yyextra->mnext = state; } while(0) #define M_ADD(t, n) \ do { \ char* c = strndup(t, n);\ sb_last(yyextra->an.markers).text = c;\ sb_last(yyextra->an.markers).offset = sb_count(yyextra->an.text);\ memcpy(sb_add(yyextra->an.text, n), c, n);\ } while(0) #define NEWANNO() \ do { \ if(!yyextra->first) sb_push(yyextra->annos, yyextra->an); \ memset(&yyextra->an, 0, sizeof(yyextra->an));\ yyextra->an.line = yyextra->line;\ yyextra->first = false;\ } while(0) #define CHECKESCAPE(x) do { if(!strchr("[]:@~\\", x)) HMML_ERR("Unknown backslash escape code '%c'", x); } while(0) %} %option reentrant %option extra-type="HMML_ParseState*" %option noyywrap S [\t \r]* ATTR_SIMPLE [^\" \]\t\r\n][^ \]\t\r\n]* ATTR_ALNUM [0-9a-zA-Z][0-9a-zA-Z_]* ATTR_QUOTED \"([^\n\"\\]|\\.)*\" TAG_VIDEO_OPEN \[video TIMECODE \[[0-9]{1,2}(:[0-5][0-9]){1,2}\] BAD_TIMECODE \[[0-9]{1,2}(:[6-9][0-9]){1,2}\] TEXT_BREAK [^\\:@~\[\]\r\n\t ] LB \[ RB \] %s VIDEO %s V_ATTR %s ANNOTATION %s TEXT_START %s TEXT %s MARKER %s MARKER_XTRA %s REF %s R_ATTR %s AFTERTEXT %s AUTHOR %s CATEGORIES %s QUOTES %% <> { HMML_ERR("Unexpected EOF, video close tag not found."); } \r\n|\n { yyextra->line++; } {TAG_VIDEO_OPEN} { BEGIN(VIDEO); } . { HMML_ERR("Missing video tag."); }