1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
2024-07-22 01:58:46 -03:00

275 lines
3.9 KiB
Plaintext
Executable File

%{
/* isp.y - Internal Signaling Protocol test generator language */
/* Written 1997,1998 by Werner Almesberger, EPFL-ICA */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <atm.h>
#include <linux/atmsvc.h>
#include "isp.h"
static struct atmsvc_msg msg;
%}
%union {
char *str;
int num;
enum atmsvc_msg_type type;
VAR *var;
};
%token TOK_SEND TOK_WAIT TOK_RECEIVE TOK_HELP TOK_SET TOK_SHOW TOK_ECHO
%token TOK_VCC TOK_LISTEN TOK_LISTEN_VCC TOK_REPLY TOK_PVC
%token TOK_LOCAL TOK_QOS TOK_SVC TOK_BIND TOK_CONNECT TOK_ACCEPT
%token TOK_REJECT TOK_LISTEN TOK_OKAY TOK_ERROR TOK_INDICATE
%token TOK_CLOSE TOK_ITF_NOTIFY TOK_MODIFY TOK_SAP
%token TOK_IDENTIFY TOK_TERMINATE TOK_EOL
%token <str> TOK_VALUE TOK_VARIABLE
%type <type> type
%type <num> field_type number
%type <var> new_var old_var
%%
all:
| command all
;
command:
TOK_SEND type
{
memset(&msg,0,sizeof(msg));
msg.type = $2;
}
values
{
send_msg(&msg);
if (verbose) dump_msg("SENT",&msg);
}
| TOK_RECEIVE
{
recv_msg(&msg);
if (!quiet) dump_msg("RECV",&msg);
}
opt_recv
| TOK_WAIT number
{
sleep($2);
}
| TOK_SET new_var '=' TOK_VALUE
{
assign($2,eval(vt_text,$4));
free($4);
}
| TOK_SHOW
{
VAR *var;
for (var = variables; var; var = var->next) {
printf("%s = ",var->name);
print_value(var->value);
putchar('\n');
}
}
| TOK_ECHO TOK_VALUE
{
printf("%s\n",$2);
free($2);
}
| help
{
fprintf(stderr,
"Commands:\n"
" send msg_type [field=value|field=$var ...]\n"
" receive [msg_type [field=value|field=$var|$var=field ...]]\n"
" set $var=value\n"
" show\n"
" echo value\n"
" help\n\n"
"msg_type: bind, connect, accept, reject, listen, okay, error, indicate,\n"
" close, itf_notify, modify, identify, terminate\n"
"field: vcc, listen_vcc, reply, pvc, local, qos, svc, sap\n");
}
| TOK_EOL
;
type:
TOK_BIND
{
$$ = as_bind;
}
| TOK_CONNECT
{
$$ = as_connect;
}
| TOK_ACCEPT
{
$$ = as_accept;
}
| TOK_REJECT
{
$$ = as_reject;
}
| TOK_LISTEN
{
$$ = as_listen;
}
| TOK_OKAY
{
$$ = as_okay;
}
| TOK_ERROR
{
$$ = as_error;
}
| TOK_INDICATE
{
$$ = as_indicate;
}
| TOK_CLOSE
{
$$ = as_close;
}
| TOK_ITF_NOTIFY
{
$$ = as_itf_notify;
}
| TOK_MODIFY
{
$$ = as_modify;
}
| TOK_IDENTIFY
{
$$ = as_identify;
}
| TOK_TERMINATE
{
$$ = as_terminate;
}
;
values:
| value values
;
value:
field_type '=' old_var
{
cast($3,type_of($1));
store(&msg,$1,$3->value);
}
| field_type '=' TOK_VALUE
{
store(&msg,$1,eval(type_of($1),$3));
free($3);
}
;
number:
TOK_VALUE
{
char *end;
$$ = strtol($1,&end,10);
if (*end) yyerror("invalid number");
free($1);
}
;
opt_recv:
| type
{
if (msg.type != $1) yyerror("wrong message type");
}
fields
;
fields:
| field fields
;
field:
new_var '=' field_type
{
assign($1,pick(&msg,$3));
}
| field_type '=' old_var
{
cast($3,type_of($1));
check(pick(&msg,$1),$3->value);
}
| field_type '=' TOK_VALUE
{
check(pick(&msg,$1),eval(type_of($1),$3));
free($3);
}
;
field_type:
TOK_VCC
{
$$ = F_VCC;
}
| TOK_LISTEN_VCC
{
$$ = F_LISTEN_VCC;
}
| TOK_REPLY
{
$$ = F_REPLY;
}
| TOK_PVC
{
$$ = F_PVC;
}
| TOK_LOCAL
{
$$ = F_LOCAL;
}
| TOK_QOS
{
$$ = F_QOS;
}
| TOK_SVC
{
$$ = F_SVC;
}
| TOK_SAP
{
$$ = F_SAP;
}
;
help:
TOK_HELP
| '?'
;
new_var:
TOK_VARIABLE
{
$$ = lookup($1);
if ($$) free($1);
else $$ = create_var($1);
}
;
old_var:
TOK_VARIABLE
{
$$ = lookup($1);
if (!$$) yyerror("no such variable");
free($1);
}
;