Back to home page

OSCL-LXR

 
 

    


0001 %option prefix="expr_"
0002 %option reentrant
0003 %option bison-bridge
0004 
0005 %{
0006 #include <linux/compiler.h>
0007 #include "expr.h"
0008 #include "expr-bison.h"
0009 #include <math.h>
0010 
0011 char *expr_get_text(yyscan_t yyscanner);
0012 YYSTYPE *expr_get_lval(yyscan_t yyscanner);
0013 
0014 static double __value(YYSTYPE *yylval, char *str, int token)
0015 {
0016         double num;
0017 
0018         errno = 0;
0019         num = strtod(str, NULL);
0020         if (errno)
0021                 return EXPR_ERROR;
0022 
0023         yylval->num = num;
0024         return token;
0025 }
0026 
0027 static int value(yyscan_t scanner)
0028 {
0029         YYSTYPE *yylval = expr_get_lval(scanner);
0030         char *text = expr_get_text(scanner);
0031 
0032         return __value(yylval, text, NUMBER);
0033 }
0034 
0035 /*
0036  * Allow @ instead of / to be able to specify pmu/event/ without
0037  * conflicts with normal division.
0038  */
0039 static char *normalize(char *str, int runtime)
0040 {
0041         char *ret = str;
0042         char *dst = str;
0043 
0044         while (*str) {
0045                 if (*str == '\\')
0046                         *dst++ = *++str;
0047                 else if (*str == '?') {
0048                         char *paramval;
0049                         int i = 0;
0050                         int size = asprintf(&paramval, "%d", runtime);
0051 
0052                         if (size < 0)
0053                                 *dst++ = '0';
0054                         else {
0055                                 while (i < size)
0056                                         *dst++ = paramval[i++];
0057                                 free(paramval);
0058                         }
0059                 }
0060                 else
0061                         *dst++ = *str;
0062                 str++;
0063         }
0064 
0065         *dst = 0x0;
0066         return ret;
0067 }
0068 
0069 static int str(yyscan_t scanner, int token, int runtime)
0070 {
0071         YYSTYPE *yylval = expr_get_lval(scanner);
0072         char *text = expr_get_text(scanner);
0073 
0074         yylval->str = normalize(strdup(text), runtime);
0075         if (!yylval->str)
0076                 return EXPR_ERROR;
0077 
0078         yylval->str = normalize(yylval->str, runtime);
0079         return token;
0080 }
0081 
0082 static int literal(yyscan_t scanner)
0083 {
0084         YYSTYPE *yylval = expr_get_lval(scanner);
0085 
0086         yylval->num = expr__get_literal(expr_get_text(scanner));
0087         if (isnan(yylval->num))
0088                 return EXPR_ERROR;
0089 
0090         return LITERAL;
0091 }
0092 %}
0093 
0094 number          ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)(e-?[0-9]+)?
0095 
0096 sch             [-,=]
0097 spec            \\{sch}
0098 sym             [0-9a-zA-Z_\.:@?]+
0099 symbol          ({spec}|{sym})+
0100 literal         #[0-9a-zA-Z_\.\-]+
0101 
0102 %%
0103         struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
0104 
0105 d_ratio         { return D_RATIO; }
0106 max             { return MAX; }
0107 min             { return MIN; }
0108 if              { return IF; }
0109 else            { return ELSE; }
0110 source_count    { return SOURCE_COUNT; }
0111 {literal}       { return literal(yyscanner); }
0112 {number}        { return value(yyscanner); }
0113 {symbol}        { return str(yyscanner, ID, sctx->runtime); }
0114 "|"             { return '|'; }
0115 "^"             { return '^'; }
0116 "&"             { return '&'; }
0117 "<"             { return '<'; }
0118 ">"             { return '>'; }
0119 "-"             { return '-'; }
0120 "+"             { return '+'; }
0121 "*"             { return '*'; }
0122 "/"             { return '/'; }
0123 "%"             { return '%'; }
0124 "("             { return '('; }
0125 ")"             { return ')'; }
0126 ","             { return ','; }
0127 .               { }
0128 %%
0129 
0130 int expr_wrap(void *scanner __maybe_unused)
0131 {
0132         return 1;
0133 }