brintos

brintos / linux-shallow public Read only

0
0
Text · 2.8 KiB · a2fc431 Raw
150 lines · plain
1%option prefix="expr_"2%option reentrant3%option bison-bridge4 5%{6#include <linux/compiler.h>7#include "expr.h"8#include "expr-bison.h"9#include <math.h>10 11char *expr_get_text(yyscan_t yyscanner);12YYSTYPE *expr_get_lval(yyscan_t yyscanner);13 14static double __value(YYSTYPE *yylval, char *str, int token)15{16	double num;17 18	errno = 0;19	num = strtod(str, NULL);20	if (errno)21		return EXPR_ERROR;22 23	yylval->num = num;24	return token;25}26 27static int value(yyscan_t scanner)28{29	YYSTYPE *yylval = expr_get_lval(scanner);30	char *text = expr_get_text(scanner);31 32	return __value(yylval, text, NUMBER);33}34 35/*36 * Allow @ instead of / to be able to specify pmu/event/ without37 * conflicts with normal division.38 */39static char *normalize(char *str, int runtime)40{41	char *ret = str;42	char *dst = str;43 44	while (*str) {45		if (*str == '\\') {46			*dst++ = *++str;47			if (!*str)48				break;49		}50		else if (*str == '?') {51			char *paramval;52			int i = 0;53			int size = asprintf(&paramval, "%d", runtime);54 55			if (size < 0)56				*dst++ = '0';57			else {58				while (i < size)59					*dst++ = paramval[i++];60				free(paramval);61			}62		}63		else64			*dst++ = *str;65		str++;66	}67 68	*dst = 0x0;69	return ret;70}71 72static int str(yyscan_t scanner, int token, int runtime)73{74	YYSTYPE *yylval = expr_get_lval(scanner);75	char *text = expr_get_text(scanner);76 77	yylval->str = normalize(strdup(text), runtime);78	if (!yylval->str)79		return EXPR_ERROR;80 81	yylval->str = normalize(yylval->str, runtime);82	return token;83}84 85static int literal(yyscan_t scanner, const struct expr_scanner_ctx *sctx)86{87	YYSTYPE *yylval = expr_get_lval(scanner);88 89	yylval->num = expr__get_literal(expr_get_text(scanner), sctx);90	if (isnan(yylval->num)) {91		if (!sctx->is_test)92			return EXPR_ERROR;93		yylval->num = 1;94	}95	return LITERAL;96}97 98static int nan_value(yyscan_t scanner)99{100	YYSTYPE *yylval = expr_get_lval(scanner);101 102	yylval->num = NAN;103	return NUMBER;104}105%}106 107number		([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)?108 109sch		[-,=]110spec		\\{sch}111sym		[0-9a-zA-Z_\.:@?]+112symbol		({spec}|{sym})+113literal		#[0-9a-zA-Z_\.\-]+114 115%%116	struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);117 118d_ratio		{ return D_RATIO; }119max		{ return MAX; }120min		{ return MIN; }121if		{ return IF; }122else		{ return ELSE; }123source_count	{ return SOURCE_COUNT; }124has_event	{ return HAS_EVENT; }125strcmp_cpuid_str	{ return STRCMP_CPUID_STR; }126NaN		{ return nan_value(yyscanner); }127{literal}	{ return literal(yyscanner, sctx); }128{number}	{ return value(yyscanner); }129{symbol}	{ return str(yyscanner, ID, sctx->runtime); }130"|"		{ return '|'; }131"^"		{ return '^'; }132"&"		{ return '&'; }133"<"		{ return '<'; }134">"		{ return '>'; }135"-"		{ return '-'; }136"+"		{ return '+'; }137"*"		{ return '*'; }138"/"		{ return '/'; }139"%"		{ return '%'; }140"("		{ return '('; }141")"		{ return ')'; }142","		{ return ','; }143.		{ }144%%145 146int expr_wrap(void *scanner __maybe_unused)147{148	return 1;149}150