-#!/bin/expect
+#!/usr/bin/expect
-set f [open "copt.txt"]
+# takes a list of command format strings
+# and feeds them to the test grammar
+# parser
+
+set f [open [lindex $argv 0]]
set cmds [split [read $f] "\n"]
close $f
spawn vtysh
foreach command $cmds {
- expect "dell-s6000-16#"
- send "$command\r"
+ expect {
+ "dell-s6000-16#" {
+ send "grammar parse $command\r"
+ }
+ "Grammar error" {
+ send_user "$command"
+ send "exit\r"
+ exit
+ }
+ }
}
interact
return node;
}
-struct graph_node *
-copy_node (struct graph_node *node)
-{
- struct graph_node *new = new_node(node->type);
- new->children = NULL;
- new->is_start = node->is_start;
- new->end = node->end;
- new->text = node->text ? XSTRDUP(MTYPE_CMD_TOKENS, node->text) : NULL;
- new->value = node->value;
- new->min = node->min;
- new->max = node->max;
- new->element = node->element ? copy_cmd_element(node->element) : NULL;
- new->arg = node->arg ? XSTRDUP(MTYPE_CMD_TOKENS, node->arg) : NULL;
- new->refs = 0;
- return new;
-}
-
void
free_node (struct graph_node *node)
{
if (!node) return;
- vector_free (node->children);
- free_cmd_element (node->element);
+ if (node->children) vector_free (node->children);
+ if (node->element) free_cmd_element (node->element);
free (node->text);
free (node->arg);
free (node);
struct graph_node *
new_node(enum graph_node_type);
-/**
- * Copies a node.
- * The children vector is copied, but the pointers the vector
- * holds point to the same data as the original vector.
- * The element, if it exists, is copied.
- *
- * @param[in] pointer to node to copy
- * @return pointer to copied node
- */
-struct graph_node *
-copy_node(struct graph_node *);
-
/**
* Frees the data associated with a graph_node.
* @param[out] pointer to graph_node to free
extern void set_buffer_string(const char *);
%}
-WORD [a-z][-_a-z0-9]+
+WORD [-+a-z\*][-+_a-zA-Z0-9\*]*
IPV4 A\.B\.C\.D
IPV4_PREFIX A\.B\.C\.D\/M
IPV6 X:X::X:X
IPV6_PREFIX X:X::X:X\/M
-VARIABLE [A-Z][A-Z_:]+
+VARIABLE [A-Z][-_a-zA-Z:0-9]+
NUMBER [0-9]{1,20}
RANGE \({NUMBER}\-{NUMBER}\)
/* matching functions */
+static struct graph_node *
+copy_node (struct graph_node *node)
+{
+ struct graph_node *new = new_node(node->type);
+ new->children = NULL;
+ new->is_start = node->is_start;
+ new->end = NULL;
+ new->text = node->text ? XSTRDUP(MTYPE_CMD_TOKENS, node->text) : NULL;
+ new->value = node->value;
+ new->min = node->min;
+ new->max = node->max;
+ new->element = node->element ? copy_cmd_element(node->element) : NULL;
+ new->arg = node->arg ? XSTRDUP(MTYPE_CMD_TOKENS, node->arg) : NULL;
+ new->refs = 0;
+ return new;
+}
+
+
/* Linked list data deletion callback */
static void
free_nodelist (void *node) {
if (*argv) break;
}
+ // walk the list, find the END_GN, return that
if (*argv) {
- // copy the nodes we need
struct listnode *ln;
struct graph_node *gn;
char buf[50];
if (match_token(start, vector_slot(vline, n), FILTER_RELAXED) < minmatch)
return NULL;
- // arg list for this subgraph
- struct list *argv;
-
// pointers for iterating linklist
struct graph_node *gn;
struct listnode *ln;
struct graph_node *curr = copy_node(start);
curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
// initialize a new argument list
- argv = list_new();
+ struct list *argv = list_new();
argv->del = &free_nodelist;
- // push the currnode
- listnode_add(argv, curr);
- // push the endnode
+ // add the current node
+ listnode_add(argv, copy_node(curr));
+ // push the end node
listnode_add(argv, copy_node(gn));
// clean up
list_delete (next);
}
if (bestmatch) {
- argv = list_new();
- listnode_add(argv, start);
- list_add_list(argv, bestmatch);
- list_free (bestmatch);
+ struct graph_node *curr = copy_node(start);
+ curr->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
+ list_add_node_prev (bestmatch, bestmatch->head, curr);
+ // cleanup
list_delete (next);
- start->arg = XSTRDUP(MTYPE_CMD_TOKENS, vector_slot(vline, n));
- return argv;
+ return bestmatch;
}
else
return NULL;
void yyerror(char const *message) {
// fail on bad parse
fprintf(stderr, "Grammar error: %s\n", message);
+ fprintf(stderr, "Token on error: ");
+ if (yylval.string) fprintf(stderr, "%s\n", yylval.string);
+ else if (yylval.node) fprintf(stderr, "%s\n", yylval.node->text);
+ else fprintf(stderr, "%d\n", yylval.integer);
+
}
struct graph_node *