%{ #include #include #include #include #include #include #include #include #include extern FILE *yyin; static size_t errors; enum filter_dir { GTW_IN, GTW_OUT, GTW_INOUT }; #define GODROP 0 enum filter_action { GTW_DROP = 0, GTW_PASS, }; struct mqtt_rule { char topic[128]; char from[128]; enum filter_action action; enum filter_dir dir; int log; int quick; }; static size_t parsed_lines; %} %union { int64_t number; char *string; }; %token ACTION IN OUT FROM QUICK LOG SOCKET %token TOPIC WORD %token ANY FROM %token SLASH HYPHEN %token WORD SOCKET %token NUMBER %type ACTION DIR QUICK LOG %type from topic %% ruleset: /* empty */ | ruleset mqttrule ; mqttrule : ACTION DIR topic from { parsed_lines++; struct mqtt_rule r; memset(&r, 0, sizeof(r)); r.action = $1; r.dir = $2; if ($3) strlcpy(r.topic, $3, sizeof r.topic); if ($4) strlcpy(r.from, $4, sizeof r.from); printf("%s %s %s.\n", r.action == GTW_DROP ? "Drop" : "pass", r.topic[0]!=0 ? r.topic :"*", r.from[0]!=0 ? r.from : ""); }; topic : ANY {$$=NULL;} | WORD {$$=$1;} ; from : /* empty */ {$$=NULL;} | FROM SOCKET {$$ = $2;} ; %% void yyerror(msg) char *msg; { fprintf(stderr, "while parsing \"%s\"\n", msg); return; } int main( int argc, char **argv ) { ++argv, --argc; /* skip over program name */ if ( argc > 0 ) yyin = fopen( argv[0], "r" ); else yyin = stdin; yyparse(); printf("\n#%zu.\n", parsed_lines); }