summaryrefslogtreecommitdiff
path: root/expr.y
diff options
context:
space:
mode:
Diffstat (limited to 'expr.y')
-rw-r--r--expr.y116
1 files changed, 111 insertions, 5 deletions
diff --git a/expr.y b/expr.y
index b2f2061..f409c5c 100644
--- a/expr.y
+++ b/expr.y
@@ -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();
+}