diff options
Diffstat (limited to 'expr.y')
-rw-r--r-- | expr.y | 116 |
1 files changed, 111 insertions, 5 deletions
@@ -1,16 +1,27 @@ %{ +#define _XOPEN_SOURCE 700 +#include <locale.h> +#include <string.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <unistd.h> +#include <inttypes.h> + +typedef struct { + int type; + union { + intmax_t i; + char *s; + } u; +} expr_yystype; + +#define YYSTYPE expr_yystype -#include "expr.h" #include "y.tab.h" -extern int yylex(void); +static int yylex(void); extern int yyerror(const char *s); -static void breakpoint(void) { } - static void expr_only_integers(YYSTYPE *y1, YYSTYPE *y2) { if (y1->type == STRING) { @@ -140,3 +151,98 @@ expr : STRING { printf("or\n"); } ; + +%% + + +/* + +"|" return '|'; +"&" return '&'; +"=" return '='; +">" return '>'; +">=" return GE; +"<" return '<'; +"<=" return LE; +"!=" return NE; +"+" return '+'; +"-" return '-'; +"*" return '*'; +"/" return '/'; +"%" return '%'; +"(" return '('; +")" return ')'; +":" return ':'; +{DIGIT}+ { yylval.u.i = atoi(yytext); return yylval.type = INTEGER; } +-{DIGIT}+ { yylval.u.i = atoi(yytext); return yylval.type = INTEGER; } +.+ { yylval.u.s = strdup(yytext); return yylval.type = STRING; } +\n ; + +*/ + +static char **expr_args; + +static int yylex(void) +{ + if (expr_args[optind] == NULL) { + return YYEOF; + } + + char *s = expr_args[optind]; + + if (strlen(s) == 1) { + char c = s[0]; + if (strchr("|&=+-*/%():", c)) { + optind++; + return c; + } + } + + if (strlen(s) == 2) { + if (!strcmp(s, ">=")) { + optind++; + return GE; + } + if (!strcmp(s, "<=")) { + optind++; + return LE; + } + if (!strcmp(s, "!=")) { + optind++; + return NE; + } + } + + char *end = NULL; + yylval.type = INTEGER; + yylval.u.i = strtoimax(s, &end, 10); + if (end && *end != '\0') { + yylval.type = STRING; + yylval.u.s = s; + } + + optind++; + return yylval.type; +} + +int main(int argc, char *argv[]) +{ + setlocale(LC_ALL, ""); + + int c; + while ((c = getopt(argc, argv, "")) != -1) { + switch (c) { + default: + return -1; + } + } + + if (optind >= argc) { + fprintf(stderr, "expr: missing operands\n"); + return 1; + } + + expr_args = argv; + + return yyparse(); +} |