DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T y

⟦8289424a3⟧ TextFile

    Length: 15119 (0x3b0f)
    Types: TextFile
    Names: »yacc.y«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/yacc.y« 

TextFile

/*
 * Copyright (C) 1986   Alan Kent
 *
 * Permission is granted to freely distribute part or
 * all of this code as long as it is not for profit
 * and this message is retained in the code.
 *
 * No resposibility is taken for any damage or incorect
 * results this program generates.
 * 
 */


/* Declaration section */

%{

#include <stdio.h>
#include <math.h>
#include "graph.h"

#define LARGE_INT	16000

extern char *new ();
extern double floor ();
extern table_st *read_table ();
extern table_st *load_table ();
extern attr_st *attr_node ();
extern double eval ();
extern table_st *eval_tab ();
extern tnode_st *tab_node ();
extern parm_st *parm_node ();
extern char *ctime ();

extern int gargc;
extern char **gargv;
extern axis_st xaxis;
extern axis_st yaxis;
extern graph_st graph[];
extern int num_graphs;
extern char *graph_label;
extern int horiz_legend;
extern int vert_legend;


static axis_st *paxis;


%}

%union {
    attr_st *attr_expr;
    table_st *table;
    tnode_st *tnode;
    double number;
    char *string;
    expr_list_st *expr_list;
    range_st *range;
    int_st *interval;
    int integer;
    parm_st *parm;
    tcol_st *tcol;
    trow_st *trow;
}

%left JOIN SORT GROUP CUMULATE
%left BY
%left APPEND
%left ADJACENT
%left '[' WHERE
%left <string> STRING IDENT TAB_IDENT VAR_IDENT FTAB_IDENT FVAR_IDENT
%left <number> NUMBER 

%type <string> string_expr string_sub_expr
%type <trow> table_line_list
%type <tcol> table_line
%type <number> constant
%type <attr_expr> expr or_op and_op rel_op add_op mul_op primary attr
%type <expr_list> expr_list
%type <range> range
%type <interval> interval
%type <string> group_function 
%type <tnode> table
%type <parm> dec_parm_list dec_parm call_parm_list call_parm

%start program

%token READ SHELL PRINT TABLE XAXIS YAXIS PLOT GRAPH VALUE INCLUDE
%token APPEND SORT JOIN GROUP BY WHERE INTO INTERVAL SIZE FROM TO WITH
%token PERFORMING ADJACENT DATE PARAMETER SAVE LOAD AS
%token LBRACKET RBRACKET LPAREN RPAREN
%token EQ NE GE GT LE LT PLUS MINUS DIVIDE MULTIPLY AND OR NOT NEG
%token IDENT TAB_IDENT VAR_IDENT STRING ATTR NUMBER FTAB_IDENT FVAR_IDENT
%token TICK LABEL FORMAT AUTO NO SCALE FRAME GRID OUTLINE AXIS 
%token LOGRITHMIC LINEAR DOTTED SOLID LONGDASHED SHORTDASHED DOTDASHED LINE
%token QUEST COLON MODULUS TAB_CONST PROJECT CUMULATE GENERATE
%token TRIANGLE CIRCLE SQUARE CROSS POINTS POWER
%token PUT LEGEND AT TOP MIDDLE BOTTOM LEFT CENTER RIGHT
%token STR VAL PARMS ASSUME



%%

/* Rules section */


program:	statement_list
			{
			    if ( num_graphs > 0 ) {
				dump_graphs ();
				reset_graphs ();
			    }
			}
	;

statement_list:	
	|	statement statement_list
	;


statement:	';'
	|	IDENT EQ table
			{ tab_declare ( $1 , eval_tab ( $3 ) ); }
	|	TAB_IDENT EQ table
			{ tab_declare ( $1 , eval_tab ( $3 ) ); }
	|	IDENT EQ expr
			{ var_declare ( $1 , eval ( NULL , 0 , $3 ) ); }
	|	VAR_IDENT EQ expr
			{ var_declare ( $1 , eval ( NULL , 0 , $3 ) ); }
	|	IDENT '(' dec_parm_list ')' EQ expr
			{ fun_declare ( $1 , $3 , $6 , NULL ); }
	|	IDENT '(' dec_parm_list ')' EQ table
			{ fun_declare ( $1 , $3 , NULL , $6 ); }
	|	INCLUDE string_expr
			{ include ( $2 ); release ( $2 ); }
	|	SHELL string_expr
			{ system ( $2 ); /* use >file */ release ( $2 ); }
	|	SAVE table AS string_expr
			{ save_table ( $4 , eval_tab ( $2 ) ); release ( $4 ); }
	|	PRINT GT GT string_expr table
			{ print_table ( eval_tab ( $5 ) , $4 , "a" ); release ( $4 ); }
	|	PRINT GT string_expr table
			{ print_table ( eval_tab ( $4 ) , $3 , "w" ); release ( $3 ); }
	|	PRINT table
			{ print_table ( eval_tab ( $2 ) , NULL , NULL ); }
	|	PRINT GT GT string_expr expr
			{ print_expr ( eval ( NULL , 0 , $5 ) , $4 , "a" ); release ( $4 ); }
	|	PRINT GT string_expr expr
			{ print_expr ( eval ( NULL , 0 , $4 ) , $3 , "w" ); release ( $3 ); }
	|	PRINT expr
			{ print_expr ( eval ( NULL , 0 , $2 ) , NULL , NULL ); }
	|	PRINT GT GT string_expr string_expr
			{ print_string ( $5 , $4 , "a" ); release ( $4 ); release ( $5 ); }
	|	PRINT GT string_expr string_expr
			{ print_string ( $4 , $3 , "w" ); release ( $3 ); release ( $4 ); }
	|	PRINT string_expr
			{ print_string ( $2 , NULL , NULL ); release ( $2 ); }
	|	graph
	|	XAXIS
			{ paxis = &xaxis; }
		axis
	|	YAXIS
			{ paxis = &yaxis; }
		axis
	|	PUT LEGEND AT pos_list
	|	PLOT
			{ dump_graphs (); reset_graphs (); }
	|	ASSUME expr string_expr
			{
			    if ( eval ( NULL , 0 , $2 ) == 0.0 ) {
				fprintf ( stderr , "%s\n" , $3 );
				exit ( 1 );
			    }
			    release ( $3 );
			}
	;

pos_list:	/* empty */
	|	pos pos_list
	;

pos:		LEFT
			{ horiz_legend = LEFT; }
	|	CENTER
			{ horiz_legend = CENTER; }
	|	RIGHT
			{ horiz_legend = RIGHT; }
	|	TOP
			{ vert_legend = TOP; }
	|	MIDDLE
			{ vert_legend = MIDDLE; }
	|	BOTTOM
			{ vert_legend = BOTTOM; }
	;

table	:	READ string_expr
			{
			    $$ = tab_node ( TAB_CONST );
			    $$->table = read_table ( $2 , -1 , -1 );
			    release ( $2 );
			}
	|	READ expr BY expr string_expr
			{
			    $$ = tab_node ( TAB_CONST );
			    $$->table = read_table ( $5 ,
				    (int)eval ( NULL , 0 , $2 ) ,
				    (int)eval ( NULL , 0 , $4 ) );
			    release ( $5 );
			}
	|	LOAD string_expr
			{
			    $$ = tab_node ( TAB_CONST );
			    $$->table = load_table ( $2 );
			    release ( $2 );
			}
	|	'{' table_line_list '}'
			{
			    $$ = tab_node ( TABLE );
			    $$->const_table = $2;
			}
	|	GENERATE range interval
			{
			    $$ = tab_node ( GENERATE );
			    $$->range = $2;
			    $$->interval = $3;
			}
	|	table APPEND table
			{
			    $$ = tab_node ( APPEND );
			    $$->left = $1;
			    $$->right = $3;
			}
	|	table ADJACENT table
			{
			    $$ = tab_node ( ADJACENT );
			    $$->left = $1;
			    $$->right = $3;
			}
	|	table '[' expr_list ']'
			{
			    $$ = tab_node ( PROJECT );
			    $$->left = $1;
			    $$->expr_list = $3;
			}
	|	table WHERE expr
			{
			    $$ = tab_node ( WHERE );
			    $$->left = $1;
			    $$->expr = $3;
			}
	|	SORT table BY attr
			{
			    $$ = tab_node ( SORT );
			    $$->left = $2;
			    $$->expr = $4;
			}
	|	JOIN table ',' table BY attr ',' attr
			{
			    $$ = tab_node ( JOIN );
			    $$->left = $2;
			    $$->right = $4;
			    $$->expr = attr_node ( JOIN , (double)0.0 , $6 , $8 );
			}
	|	CUMULATE table BY attr
			{
			    $$ = tab_node ( CUMULATE );
			    $$->left = $2;
			    $$->expr = $4;
			}
	|	GROUP table range interval PERFORMING group_function
			{
			    $$ = tab_node ( GROUP );
			    $$->left = $2;
			    $$->range = $3;
			    $$->interval = $4;
			    $$->ident = $6;
			}
	|	'(' table ')'
			{ $$ = $2; }
	|	IDENT
			{ abort ( "Undefined identifier" ); }
	|	FTAB_IDENT '(' call_parm_list ')'
			{
			    $$ = tab_node ( FTAB_IDENT );
			    $$->ident = $1;
			    $$->parm_list = $3;
			}
	|	TAB_IDENT
			{ $$ = tab_node ( TAB_IDENT ); $$->ident = $1; }
	;

group_function:
		FVAR_IDENT
			{ $$ = $1; check_group_fun ( $1 ); }
	;

table_line_list:	
			{ $$ = NULL; }
	|	'{' table_line '}' table_line_list
			{
			    $$ = (trow_st *) new ( sizeof ( trow_st ) );
			    $$->cols = $2;
			    $$->next = $4;
			}
	;

table_line:	expr
			{
			    $$ = (tcol_st *) new ( sizeof ( tcol_st ) );
			    $$->expr = $1;
			    $$->next = NULL;
			}
	|
		expr ',' table_line
			{
			    $$ = (tcol_st *) new ( sizeof ( tcol_st ) );
			    $$->expr = $1;
			    $$->next = $3;
			}
	;

attr	:	'$' primary
			{ $$ = $2; }
	;

expr	:	or_op '?' or_op ':' or_op
			{ $$ = attr_node ( QUEST , (double)0.0 , $1 ,
			    attr_node ( COLON , (double)0.0 , $3 , $5 ) ); }
	|	or_op
			{ $$ = $1; }
	;

or_op	:	and_op '|' or_op
			{ $$ = attr_node ( OR , (double)0.0 , $1 , $3 ); }
	|	and_op
			{ $$ = $1; }
	;

and_op	:	rel_op '&' and_op
			{ $$ = attr_node ( AND , (double)0.0 , $1 , $3 ); }
	|	rel_op
			{ $$ = $1; }
	;

rel_op	:	add_op EQ add_op
			{ $$ = attr_node ( EQ , (double)0.0 , $1 , $3 ); }
	|	add_op NE add_op
			{ $$ = attr_node ( NE , (double)0.0 , $1 , $3 ); }
	|	add_op LE add_op
			{ $$ = attr_node ( LE , (double)0.0 , $1 , $3 ); }
	|	add_op LT add_op
			{ $$ = attr_node ( LT , (double)0.0 , $1 , $3 ); }
	|	add_op GE add_op
			{ $$ = attr_node ( GE , (double)0.0 , $1 , $3 ); }
	|	add_op GT add_op
			{ $$ = attr_node ( GT , (double)0.0 , $1 , $3 ); }
	|	add_op
			{ $$ = $1; }
	;

add_op	:	mul_op '+' add_op
			{ $$ = attr_node ( PLUS , (double)0.0 , $1 , $3 ); }
	|	mul_op '-' add_op
			{ $$ = attr_node ( MINUS , (double)0.0 , $1 , $3 ); }
	|	mul_op
			{ $$ = $1; }
	;

mul_op	:	primary '/' mul_op
			{ $$ = attr_node ( DIVIDE , (double)0.0 , $1 , $3 ); }
	|	primary '*' mul_op
			{ $$ = attr_node ( MULTIPLY , (double)0.0 , $1 , $3 ); }
	|	primary '%' mul_op
			{ $$ = attr_node ( MODULUS , (double)0.0 , $1 , $3 ); }
	|	primary
			{ $$ = $1; }
	;

primary	:	'-' primary
			{ $$ = attr_node ( NEG , (double)0.0 , $2 , NULL ); }
	|	'!' primary
			{ $$ = attr_node ( NOT , (double)0.0 , $2 , NULL ); }
	|	'(' expr ')'
			{ $$ = $2; }
	|	attr
			{ $$ = attr_node ( ATTR , (double)0.0 , $1 , NULL ); }
	|	constant
			{ $$ = attr_node ( NUMBER , $1 , NULL , NULL ); }
	|	FVAR_IDENT '(' call_parm_list ')'
			{
			    $$ = attr_node ( FVAR_IDENT , (double)0.0 , NULL , NULL );
			    $$->ident = $1;
			    $$->parm_list = $3;
			}
	|	VAR_IDENT
			{
			    $$ = attr_node ( VAR_IDENT , (double)0.0 , NULL , NULL );
			    $$->ident = $1;
			}
	;

expr_list:	
			{ $$ = NULL; }
	|	expr
			{
			    $$ = (expr_list_st *) new ( sizeof ( expr_list_st ) );
			    $$->expr = $1;
			    $$->next = NULL;
			}
	|	expr ',' expr_list
			{
			    $$ = (expr_list_st *) new ( sizeof ( expr_list_st ) );
			    $$->expr = $1;
			    $$->next = $3;
			}
	;

interval:	WITH expr INTERVAL 
			{
			    $$ = (int_st *) new ( sizeof ( int_st ) );
			    $$->int_type = INUMINT;
			    $$->value = eval ( NULL , 0 , $2 );
			}
	|	INTERVAL SIZE expr 
			{
			    $$ = (int_st *) new ( sizeof ( int_st ) );
			    $$->int_type = ISIZE;
			    $$->value = eval ( NULL , 0 , $3 );
			}
	;

range	:	/* default min to max */
			{ $$ = NULL; }
	|	FROM expr TO expr
			{
			    $$ = (range_st *) new ( sizeof ( range_st ) );
			    $$->min = eval ( NULL , 0 , $2 );
			    $$->max = eval ( NULL , 0 , $4 );
			}
	;

constant:	NUMBER
			{ $$ = $1; }
	|	PARMS
			{ $$ = gargc - 2; }
	|	VAL '(' string_expr ')'
			{
			    double num;

			    if ( scan_value ( $3 , &num ) == NULL ) {
				warn ( "Illegal number in VAL()" );
				num = 0.0;
			    }
			    release ( $3 );
			    $$ = num;
			}
	;

axis	:	axis_option_list
	;

axis_option_list:
	|	axis_option axis_option_list
	;

axis_option:
	/*
	|	TICK range
	|	AUTO TICK
	*/
		LABEL string_expr
			{ paxis->label = $2; }
	|	FORMAT string_expr
			{ paxis->user_format = $2; }
	|	AUTO SCALE
			{ paxis->scale = AUTO; }
	|	NO SCALE
			{ paxis->scale = NO; }
	|	TICK SIZE expr POWER expr
			{
			    paxis->auto_tick_size = 0;
			    paxis->tick_size = eval ( NULL , 0 , $3 );
			    paxis->power_10 = eval ( NULL , 0 , $5 );
			}
	|	TICK SIZE expr
			{
			    paxis->auto_tick_size = 0;
			    paxis->tick_size = eval ( NULL , 0 , $3 );
			    paxis->power_10 = 0.0;	/* not good */
			}
	|	FRAME AXIS
			{ paxis->frame = FRAME; }
	|	GRID AXIS
			{ paxis->frame = GRID; }
	|	OUTLINE AXIS
			{ paxis->frame = OUTLINE; }
	|	NO AXIS
			{ paxis->frame = NO; }
	|	LOGRITHMIC
			{ paxis->linear = LOGRITHMIC; }
	|	LINEAR
			{ paxis->linear = LINEAR; }
	|	FROM expr TO expr
			{
			    paxis->range.min = eval ( NULL , 0 , $2 );
			    paxis->range.max = eval ( NULL , 0 , $4 );
			}
	;

graph	:	GRAPH table
			{
			    if ( num_graphs >= MAX_GRAPHS )
				abort ( "too many graphs" );
			    graph[ num_graphs ].line_type = SOLID;
			    graph[ num_graphs ].point_type = 0;
			    graph[ num_graphs ].cumulative = 0;
			    graph[ num_graphs ].label = NULL;
			    graph[ num_graphs ].legend = NULL;
			}
		graph_option_list
			{
			    table_st *p;

			    p = eval_tab ( $2 );
			    if ( p == NULL || p->next == NULL )
				abort ( "GRAPH requires two column tables to plot" );
			    if ( p->size < 1 )
				warn ( "No data in graph to plot" );
			    else
				graph[ num_graphs++ ].table = p;
			}
	|	GRAPH LABEL string_expr
			{
			    graph_label = $3;
			}
	;

graph_option_list:
	|	graph_option_list graph_option
	;

graph_option:	DOTTED LINE
			{ graph[ num_graphs ].line_type = DOTTED; }
	|	SOLID LINE
			{ graph[ num_graphs ].line_type = SOLID; }
	|	SHORTDASHED LINE
			{ graph[ num_graphs ].line_type = SHORTDASHED; }
	|	LONGDASHED LINE
			{ graph[ num_graphs ].line_type = LONGDASHED; }
	|	DOTDASHED LINE
			{ graph[ num_graphs ].line_type = DOTDASHED; }
	|	NO LINE
			{ graph[ num_graphs ].line_type = NO; }
	|	NO POINTS
			{ graph[ num_graphs ].point_type = 0; }
	|	TRIANGLE POINTS
			{ graph[ num_graphs ].point_type |= MSK_TRIANGLE; }
	|	CIRCLE POINTS
			{ graph[ num_graphs ].point_type |= MSK_CIRCLE; }
	|	SQUARE POINTS
			{ graph[ num_graphs ].point_type |= MSK_SQUARE; }
	|	CROSS POINTS
			{ graph[ num_graphs ].point_type |= MSK_CROSS; }
	|	PLUS POINTS
			{ graph[ num_graphs ].point_type |= MSK_PLUS; }
	|	LABEL string_expr
			{ graph[ num_graphs ].label = $2; }
	|	LEGEND string_expr
			{ graph[ num_graphs ].legend = $2; }
	;

dec_parm_list:	
			{ $$ = NULL; }
	|
		dec_parm
			{ $$ = $1; $$->next = NULL; }
	|	dec_parm ',' dec_parm_list
			{ $$ = $1; $$->next = $3; }
	;

dec_parm:	VAR_IDENT
			{ $$ = parm_node ( $1 , VALUE ); }
	|	TAB_IDENT
			{ $$ = parm_node ( $1 , TABLE ); }
	;

call_parm_list:	
			{ $$ = NULL; }
	|
		call_parm
			{ $$ = $1; $$->next = NULL; }
	|	call_parm ',' call_parm_list
			{ $$ = $1; $$->next = $3; }
	;

call_parm:	expr
			{ $$ = parm_node ( NULL , VALUE ); $$->expr = $1; }
	|	table
			{ $$ = parm_node ( NULL , TABLE ); $$->tab_expr = $1; }
	;

string_expr:	string_sub_expr
			{
			    $$ = $1;
			}
	|	string_sub_expr '+' string_expr
			{
			    char *p;

			    p = new ( strlen ( $1 ) + strlen ( $3 ) + 1 );
			    strcpy ( p , $1 );
			    strcat ( p , $3 );
			    release ( $1 );
			    release ( $3 );
			    $$ = p;
			}
	;

string_sub_expr: STRING
			{
			    char *p;

			    p = new ( strlen ( $1 ) + 1 );
			    strcpy ( p , $1 );
			    $$ = p;
			}
	|	PARAMETER constant
			{
			    char *p;
			    int i;

			    i = $2;
			    if ( i > gargc - 2  ||  i < 1 )
				abort ( "undefined parameter" );
			    p = new ( strlen ( gargv[ i + 1 ] ) + 1 );
			    strcpy ( p , gargv[ i + 1 ] );
			    $$ = p;
			}
	|	STR '(' string_expr ',' expr ')'
			{
			    char *p;
			    char buf[ 100 ];

			    sprintf ( buf , $3 , eval ( NULL , 0 , $5 ) );
			    p = new ( strlen ( buf ) + 1 );
			    strcpy ( p , buf );
			    release ( $3 );
			    $$ = p;
			}
	|	STR '(' expr ')'
			{
			    char *p;
			    char buf[ 30 ];

			    sprintf ( buf , "%g" , eval ( NULL , 0 , $3 ) );
			    p = new ( strlen ( buf ) + 1 );
			    strcpy ( p , buf );
			    $$ = p;
			}
	|	DATE
			{
			    long clock;
			    char *p , *str;
			    int i;

			    p = new ( 32 );
			    time ( &clock );
			    str = ctime ( &clock );
			    for ( i = 0; str[i] != '\n' && str[i] != '\0'; i++ )
				p[i] = str[i];
			    p[i] = '\0';
			    $$ = p;
			}
	;

%%

/* Subroutine section */