mirror of
https://codeberg.org/dnkl/yambar.git
synced 2025-04-22 12:25:38 +02:00
'-' is a valid character for tags.
Commit 03e1c7d
(module/network: Add link stats, 2022-04-30) introduced
two new tags for the network module: `ul-speed` and `dl-speed`. These
use the `-` character, that was previously never used in any tag.
We had two options: either change those tags to use `_` instead, or just
accept `-`s as a valid character. Going forward, I can see many people
deciding to name their tags with `-` instead of `_`, so I believe it is
better to just accept it once and for all.
Note that `-` cannot be used as the first character of a tag (e.g.
`-tag1`) since the `-` has a special meaning in `.yml` files. I don't
believe this will happen often, however, and should be easy to both
detect and correct if it does.
125 lines
3.2 KiB
Text
125 lines
3.2 KiB
Text
%{
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "map.h"
|
|
|
|
struct map_condition *MAP_CONDITION_PARSE_RESULT;
|
|
char *MAP_PARSER_ERROR_MSG;
|
|
|
|
static const int NUM_TOKENS = 7;
|
|
int yylex();
|
|
void yyerror(const char *str);
|
|
%}
|
|
|
|
%define parse.lac full
|
|
%define parse.error custom
|
|
|
|
%union {
|
|
char *str;
|
|
struct map_condition *condition;
|
|
enum map_op op;
|
|
}
|
|
|
|
%token WORD STRING CMP_OP L_PAR R_PAR
|
|
%left BOOL_OP
|
|
%precedence NOT
|
|
|
|
%destructor { free_map_condition($<condition>$); } condition
|
|
%destructor { free($<str>$); } WORD
|
|
%destructor { free($<str>$); } STRING
|
|
|
|
%%
|
|
result: condition { MAP_CONDITION_PARSE_RESULT = $<condition>1; };
|
|
|
|
condition:
|
|
WORD {
|
|
$<condition>$ = malloc(sizeof(struct map_condition));
|
|
$<condition>$->tag = $<str>1;
|
|
$<condition>$->op = MAP_OP_SELF;
|
|
}
|
|
|
|
|
WORD CMP_OP WORD {
|
|
$<condition>$ = malloc(sizeof(struct map_condition));
|
|
$<condition>$->tag = $<str>1;
|
|
$<condition>$->op = $<op>2;
|
|
$<condition>$->value = $<str>3;
|
|
}
|
|
|
|
|
WORD CMP_OP STRING {
|
|
$<condition>$ = malloc(sizeof(struct map_condition));
|
|
$<condition>$->tag = $<str>1;
|
|
$<condition>$->op = $<op>2;
|
|
$<condition>$->value = $<str>3;
|
|
}
|
|
|
|
|
L_PAR condition R_PAR { $<condition>$ = $<condition>2; }
|
|
|
|
|
NOT condition {
|
|
$<condition>$ = malloc(sizeof(struct map_condition));
|
|
$<condition>$->cond1 = $<condition>2;
|
|
$<condition>$->op = MAP_OP_NOT;
|
|
}
|
|
|
|
|
condition BOOL_OP condition {
|
|
$<condition>$ = malloc(sizeof(struct map_condition));
|
|
$<condition>$->cond1 = $<condition>1;
|
|
$<condition>$->op = $<op>2;
|
|
$<condition>$->cond2 = $<condition>3;
|
|
}
|
|
;
|
|
%%
|
|
|
|
void yyerror(const char *str)
|
|
{
|
|
fprintf(stderr, "error: %s\n", str);
|
|
}
|
|
|
|
static char const*
|
|
token_to_str(yysymbol_kind_t tkn)
|
|
{
|
|
switch (tkn) {
|
|
case YYSYMBOL_CMP_OP: return "==, !=, <=, <, >=, >";
|
|
case YYSYMBOL_BOOL_OP: return "||, &&";
|
|
case YYSYMBOL_L_PAR: return "(";
|
|
case YYSYMBOL_R_PAR: return ")";
|
|
case YYSYMBOL_NOT: return "~";
|
|
default: return yysymbol_name(tkn);
|
|
}
|
|
}
|
|
|
|
static int
|
|
yyreport_syntax_error (const yypcontext_t *ctx)
|
|
{
|
|
int res = 0;
|
|
char *errmsg = malloc(1024);
|
|
errmsg[0] = '\0';
|
|
|
|
// Report the tokens expected at this point.
|
|
yysymbol_kind_t expected[NUM_TOKENS];
|
|
int n = yypcontext_expected_tokens(ctx, expected, NUM_TOKENS);
|
|
if (n < 0)
|
|
res = n; // Forward errors to yyparse.
|
|
else {
|
|
for (int i = 0; i < n; ++i) {
|
|
strcat(errmsg, i == 0 ? "expected [" : ", ");
|
|
strcat(errmsg, token_to_str(expected[i]));
|
|
}
|
|
strcat(errmsg, "]");
|
|
}
|
|
|
|
// Report the unexpected token.
|
|
yysymbol_kind_t lookahead = yypcontext_token(ctx);
|
|
if (lookahead != YYSYMBOL_YYEMPTY) {
|
|
strcat(errmsg, ", found ");
|
|
if (!(lookahead == YYSYMBOL_STRING || lookahead == YYSYMBOL_WORD))
|
|
strcat(errmsg, yysymbol_name(lookahead));
|
|
else if (yylval.str != NULL)
|
|
strcat(errmsg, yylval.str);
|
|
else
|
|
strcat(errmsg, "nothing");
|
|
}
|
|
|
|
MAP_PARSER_ERROR_MSG = errmsg;
|
|
return res;
|
|
}
|