%{ /* This is a bison parser for libnslog's filter syntax * * This file is part of libnslog. * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2017 Daniel Silverstone * */ #include "nslog/nslog.h" #include #include "filter-parser.h" #include "filter-lexer.h" static void filter_error(FILTER_LTYPE *loc, nslog_filter_t **output, const char *msg) { (void)loc; (void)output; (void)msg; } %} %locations %pure-parser %parse-param { nslog_filter_t **output } %union { char *patt; nslog_level level; nslog_filter_t *filter; } %token T_PATTERN %token T_LEVEL %token T_CATEGORY_SPECIFIER %token T_FILENAME_SPECIFIER %token T_LEVEL_SPECIFIER %token T_DIRNAME_SPECIFIER %token T_FUNCNAME_SPECIFIER %token T_OP_AND %token T_OP_OR %type level_filter %type category_filter %type filename_filter %type dirname_filter %type funcname_filter %type basic_filter %type and_filter %type or_filter %type xor_filter %type binary_filter %type not_filter %type filter %type toplevel %start toplevel %% /* part ::= [^: \t\n]+ level-name ::= 'DEEPDEBUG' | 'DD' | 'DEBUG' | 'VERBOSE' | 'CHAT' | 'WARNING' | 'WARN' | 'ERROR' | 'ERR' | 'CRITICAL' | 'CRIT' category-filter ::= 'cat:' part level-filter ::= 'level:' level-name file-filter ::= 'file:' part dir-filter ::= 'dir:' dir factor ::= category-filter | level-filter | file-filter | dir-filter | '(' expression ')' op ::= '&&' | '||' | '^' | 'and' | 'or' | 'xor' | 'eor' term ::= factor {op factor} expression ::= term | '!' term */ level_filter: T_LEVEL_SPECIFIER T_LEVEL { assert(nslog_filter_level_new($2, &$$) == NSLOG_NO_ERROR); } ; category_filter: T_CATEGORY_SPECIFIER T_PATTERN { assert(nslog_filter_category_new($2, &$$) == NSLOG_NO_ERROR); } ; filename_filter: T_FILENAME_SPECIFIER T_PATTERN { assert(nslog_filter_filename_new($2, &$$) == NSLOG_NO_ERROR); } ; dirname_filter: T_DIRNAME_SPECIFIER T_PATTERN { assert(nslog_filter_dirname_new($2, &$$) == NSLOG_NO_ERROR); } ; funcname_filter: T_FUNCNAME_SPECIFIER T_PATTERN { assert(nslog_filter_funcname_new($2, &$$) == NSLOG_NO_ERROR); } ; basic_filter: level_filter | category_filter | filename_filter | dirname_filter | funcname_filter ; and_filter: '(' filter T_OP_AND filter ')' { assert(nslog_filter_and_new($2, $4, &$$) == NSLOG_NO_ERROR); nslog_filter_unref($2); nslog_filter_unref($4); } ; or_filter: '(' filter T_OP_OR filter ')' { assert(nslog_filter_or_new($2, $4, &$$) == NSLOG_NO_ERROR); nslog_filter_unref($2); nslog_filter_unref($4); } ; xor_filter: '(' filter '^' filter ')' { assert(nslog_filter_xor_new($2, $4, &$$) == NSLOG_NO_ERROR); nslog_filter_unref($2); nslog_filter_unref($4); } ; binary_filter: and_filter | or_filter | xor_filter ; not_filter: '!' filter { assert(nslog_filter_not_new($2, &$$) == NSLOG_NO_ERROR); nslog_filter_unref($2); } ; filter: not_filter | binary_filter | basic_filter ; toplevel: filter { $$ = *output = $1; } | error { (void)yylloc; YYABORT ; } ;