// route_sim.y++ by Brett Tjaden %{ using namespace std; #include #include struct interface { string name; string ip_address; string netmask; }; struct host { string name; vector interfaces; }; struct table_entry { string target; string netmask; string next_hop; }; struct routing_table { string hostname; vector table; }; struct test { string src; string dest; }; vector if_list; vector t; extern vector hosts; extern vector tests; extern vector tables; int yylex(); void yyerror(char *); %} %union { int number; char *string; } %start conf %token SUBNET NETMASK HOST INTERFACE TABLE ROUTE TEST ARROW %token NAME ADDRESS %% conf : subnets routes tests {} ; subnets : SUBNET ADDRESS NETMASK ADDRESS hosts {} | subnets SUBNET ADDRESS NETMASK ADDRESS hosts {} ; hosts : HOST NAME interfaces { vector::iterator i; for (i=hosts.begin(); ((i != hosts.end()) && ((*i).name != $2)); i++) ; if (i == hosts.end()) { struct host h; h.name = $2; h.interfaces = if_list; hosts.push_back(h); } else { vector::iterator j; for (j=if_list.begin(); j != if_list.end(); j++) (*i).interfaces.push_back(*j); } if_list.clear(); } | hosts HOST NAME interfaces { vector::iterator i; for (i=hosts.begin(); ((i != hosts.end()) && ((*i).name != $3)); i++) ; if (i == hosts.end()) { struct host h; h.name = $3; h.interfaces = if_list; hosts.push_back(h); } else { vector::iterator j; for (j=if_list.begin(); j != if_list.end(); j++) (*i).interfaces.push_back(*j); } if_list.clear(); } ; interfaces : INTERFACE NAME ADDRESS NETMASK ADDRESS { struct interface i; i.name = $2; i.ip_address = $3; i.netmask = $5; if_list.push_back(i); } | interfaces INTERFACE NAME ADDRESS NETMASK ADDRESS { struct interface i; i.name = $3; i.ip_address = $4; i.netmask = $6; if_list.push_back(i); } ; routes : TABLE NAME table { struct routing_table rt; rt.hostname = $2; rt.table = t; tables.push_back(rt); t.clear(); } | routes TABLE NAME table { struct routing_table rt; rt.hostname = $3; rt.table = t; tables.push_back(rt); t.clear(); } ; table : ROUTE ADDRESS ADDRESS ADDRESS { struct table_entry te; te.target = $2; te.netmask = $3; te.next_hop = $4; t.push_back(te); } | table ROUTE ADDRESS ADDRESS ADDRESS { struct table_entry te; te.target = $3; te.netmask = $4; te.next_hop = $5; t.push_back(te); } ; tests : TEST NAME ARROW NAME { struct test t; t.src = $2; t.dest = $4; tests.push_back(t); } | tests TEST NAME ARROW NAME { struct test t; t.src = $3; t.dest = $5; tests.push_back(t); } ; %% void yyerror(char *tmp) {}