summaryrefslogtreecommitdiff
path: root/src/cli_parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli_parse.y')
-rw-r--r--src/cli_parse.y206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/cli_parse.y b/src/cli_parse.y
new file mode 100644
index 0000000..f0e43a8
--- /dev/null
+++ b/src/cli_parse.y
@@ -0,0 +1,206 @@
+%{
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "cli_val.h"
+
+extern int yy_cli_def_lineno;
+static vtw_def *parse_defp;
+static int parse_status;
+static boolean cli_def_type_only=0; /*{ if (cli_def_type_only) YYACCEPT;}*/
+/* XXX: sigh, the -p flag to yacc should do this for us kkkk*/
+#define yystacksize tpltstacksize
+#define yysslim tpltsslim
+
+/* forward prototypes */
+extern int yy_cli_parse_parse();
+extern int yy_cli_def_lex();
+extern void yy_cli_parse_error(const char *);
+static void cli_deferror(const char *);
+ extern FILE *yy_cli_def_in;
+#define YYDEBUG 1
+#define yy_cli_parse_lex yy_cli_def_lex
+%}
+%token EOL
+%token MULTI
+%token TAG
+%token TYPE
+%token HELP
+%token DEFAULT
+%token PATTERN
+%token EXEC
+%token SYNTAX
+%token COMMIT
+%token CHECK
+%left SEMI
+%token <val>VALUE
+%token <type>TYPE_DEF
+%token <strp>VAR
+%token <strp> STRING
+%token <strp> EX_STRING
+%token SYNTAX_ERROR
+%token <action>ACTION
+%left ASSIGN
+%left OR
+%left AND
+%right NOT
+%left COMMA
+%nonassoc <cond>COND
+%token RP
+%token LP
+%type <nodep> val
+%type <nodep> exp
+%type <val> val0
+%type <nodep> action
+%type <nodep> action0
+
+%union {
+ char *strp;
+ valstruct val;
+ vtw_type_e type;
+ vtw_cond_e cond;
+ vtw_node *nodep;
+ vtw_act_type action;
+}
+
+%%
+
+input: tag
+ | EOL input
+ | tag otherinput
+ ;
+
+otherinput: type EOL
+ | cause EOL
+ | otherinput type EOL
+ | otherinput cause EOL
+ | otherinput EOL
+ | syntax_error
+ ;
+
+tag: /* empty */
+ | TAG EOL {parse_defp->tag = TRUE;}
+ | MULTI EOL {parse_defp->multi = TRUE;}
+ ;
+
+type: TYPE TYPE_DEF SEMI STRING
+ { parse_defp->def_type = $2;
+ parse_defp->def_type_help = $4; }
+ ;
+
+
+type: TYPE TYPE_DEF
+ { parse_defp->def_type = $2;
+ }
+ ;
+
+cause: help_cause
+ | default_cause
+ | syntax_cause
+ | ACTION action { append(parse_defp->actions + $1, $2, 0);}
+ ;
+
+help_cause: HELP STRING
+ { parse_defp->def_type_help = $2; /* no semantics for now */
+ }
+
+default_cause: DEFAULT VALUE
+ {
+ if ($2.val_type != parse_defp->def_type)
+ yy_cli_parse_error((const char *)"Bad default\n");
+ parse_defp->def_default = $2.val;
+ }
+default_cause: DEFAULT STRING
+ {
+ if (TEXT_TYPE != parse_defp->def_type)
+ yy_cli_parse_error((const char *)"Bad default\n");
+ parse_defp->def_default = $2;
+ }
+
+syntax_cause: SYNTAX exp {append(parse_defp->actions + syntax_act, $2, 0);}
+ ;
+
+syntax_cause: COMMIT exp {append(parse_defp->actions + syntax_act, $2, 1);}
+ ;
+
+action0: STRING { $$ = make_node(EXEC_OP, make_str_node($1),NULL);}
+ ;
+action: action0
+ | action0 SEMI STRING
+ {$$ = make_node(HELP_OP, $1, make_str_node($3));}
+ | exp
+ ;
+exp: LP exp RP
+ {$$=$2;}
+ | exp AND exp {$$ = make_node(AND_OP,$1,$3);}
+ | exp OR exp {$$ = make_node(OR_OP,$1,$3);}
+ | val COND val
+ {$$ = make_node(COND_OP,$1,$3);$$->vtw_node_aux = $2;}
+ | PATTERN VAR STRING
+ { $$ = make_node(PATTERN_OP,make_var_node($2),
+ make_str_node($3));}
+ | EXEC STRING
+ { $$ = make_node(EXEC_OP,make_str_node($2),NULL);}
+ | NOT exp {$$ = make_node(NOT_OP,$2,NULL);}
+ | exp SEMI STRING
+ {$$ = make_node(HELP_OP, $1, make_str_node($3));}
+ | VAR ASSIGN val
+ {$$ = make_node(ASSIGN_OP, make_var_node($1), $3);}
+ ;
+
+val: VAR {$$ = make_var_node($1);}
+ | val0 {$$ = make_val_node(&($1));}
+ | EX_STRING {$$=make_str_node0($1, B_QUOTE_OP);}
+ ;
+
+val0: VALUE
+
+ | val0 COMMA val0 { add_val(&($1), &($3)); $$=$1; }
+
+ | STRING {$$ = str2val($1);}
+ ;
+
+syntax_error: SYNTAX_ERROR {
+ cli_deferror("syntax error");
+ }
+ ;
+
+
+%%
+char *parse_path;
+int parse_def(vtw_def *defp, char *path, boolean type_only)
+{
+ int status;
+ yy_cli_def_lineno = 1;
+ parse_status = 0;
+ parse_defp = defp;
+ cli_def_type_only = type_only;
+ yy_cli_def_in = fopen(path, "r");
+#if 0
+ yy_cli_parse_debug = 1;
+#endif
+ if (!yy_cli_def_in)
+ return -5;
+ parse_path = path;
+ status = yy_cli_parse_parse(); /* 0 is OK */
+ fclose(yy_cli_def_in);
+ return status;
+}
+static void
+cli_deferror(const char *s)
+{
+ printf("Error: %s in file %s, line %d\n",s, parse_path,
+ yy_cli_def_lineno);
+}
+
+void yy_cli_parse_error(const char *s)
+{
+ cli_deferror(s);
+}
+
+
+
+
+