123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- %{
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <unistd.h>
- #include "mapcalc.h"
- #define YYDEBUG 1
- #define YYERROR_VERBOSE 1
- static int syntax_error_occurred;
- %}
- %union {
- int ival;
- double fval;
- char *sval;
- expression *exp;
- expr_list *list;
- }
- %token <sval> VARNAME
- %token <sval> NAME
- %token <sval> VARSTRING
- %token <sval> STRING
- %token <ival> INTEGER
- %token <fval> FLOAT
- %token <fval> DOUBLE
- %token GT GE LT LE EQ NE LOGAND LOGOR LOGAND2 LOGOR2 BITAND BITOR LSH RSH RSHU
- %type <exp> exp
- %type <exp> exp_atom
- %type <exp> exp_pre
- %type <exp> exp_pow
- %type <exp> exp_mul
- %type <exp> exp_add
- %type <exp> exp_sh
- %type <exp> exp_cmp
- %type <exp> exp_eq
- %type <exp> exp_bitand
- %type <exp> exp_bitor
- %type <exp> exp_logand
- %type <exp> exp_logor
- %type <exp> exp_cond
- %type <exp> exp_let
- %type <exp> atom_var
- %type <exp> atom_map
- %type <exp> atom_func
- %type <exp> def
- %type <ival> mapmod
- %type <ival> index
- %type <sval> name
- %type <sval> map
- %type <list> expr_list
- %type <list> defs
- %type <list> program
- %{
- static expr_list *result;
- extern int yylex(void);
- int yyparse(void);
- void yyerror(char *s);
- %}
- %%
- program : defs { $$ = result = $1; }
- ;
- defs : def { $$ = list($1,NULL); }
- | def ';' { $$ = list($1,NULL); }
- | def ';' defs { $$ = list($1,$3); }
- | error ';' defs { $$ = $3; }
- ;
- def : STRING '=' exp { $$ = binding($1,$3); define_variable($$); }
- | NAME '=' exp { $$ = binding($1,$3); define_variable($$); }
- | atom_func
- ;
- map : STRING
- | NAME
- | name '@' name { $$ = composite($1,$3); }
- ;
- mapmod : '@' { $$ = '@'; }
- | 'r' { $$ = 'r'; }
- | 'g' { $$ = 'g'; }
- | 'b' { $$ = 'b'; }
- | '#' { $$ = '#'; }
- | 'y' { $$ = 'y'; }
- | 'i' { $$ = 'i'; }
- ;
- index : INTEGER
- | '-' INTEGER { $$ = -$2; }
- ;
- expr_list : exp { $$ = singleton($1); }
- | exp ',' expr_list { $$ = list($1, $3); }
- ;
- atom_var : VARSTRING { $$ = variable($1); }
- | VARNAME { $$ = variable($1); }
- ;
- atom_map : map '[' index ']' { $$ = mapname($1,'M',$3,0,0); }
- | map '[' index ',' index ']'
- { $$ = mapname($1,'M',$3,$5,0); }
- | map '[' index ',' index ',' index ']'
- { $$ = mapname($1,'M',$3,$5,$7);}
- | map { $$ = mapname($1,'M',0,0,0); }
- | mapmod map '[' index ']'
- { $$ = mapname($2,$1,$4,0,0); }
- | mapmod map '[' index ',' index ']'
- { $$ = mapname($2,$1,$4,$6,0); }
- | mapmod map '[' index ',' index ',' index ']'
- { $$ = mapname($2,$1,$4,$6,$8); }
- | mapmod map { $$ = mapname($2,$1,0,0,0); }
- ;
- atom_func : name '(' ')' { $$ = function($1, NULL); }
- | name '(' expr_list ')'
- { $$ = function($1, $3); }
- ;
- exp_atom : '(' exp ')' { $$ = $2; }
- | atom_var
- | atom_map
- | atom_func
- | INTEGER { $$ = constant_int($1); }
- | FLOAT { $$ = constant_float($1); }
- | DOUBLE { $$ = constant_double($1); }
- ;
- exp_pre : exp_atom
- | '-' exp_atom { $$ = operator("neg","-",1,singleton($2)); }
- | '~' exp_atom { $$ = operator("bitnot","~",1,singleton($2)); }
- | '!' exp_atom { $$ = operator("not","!",1,singleton($2)); }
- ;
- exp_pow : exp_pre
- | exp_pre '^' exp_pow { $$ = operator("pow","^",2,pair($1,$3)); }
- ;
- exp_mul : exp_pow
- | exp_mul '*' exp_pow { $$ = operator("mul","*",3,pair($1,$3)); }
- | exp_mul '/' exp_pow { $$ = operator("div","/",3,pair($1,$3)); }
- | exp_mul '%' exp_pow { $$ = operator("mod","%",3,pair($1,$3)); }
- ;
- exp_add : exp_mul
- | exp_add '+' exp_mul { $$ = operator("add","+",4,pair($1,$3)); }
- | exp_add '-' exp_mul { $$ = operator("sub","-",4,pair($1,$3)); }
- ;
- exp_sh : exp_add
- | exp_sh LSH exp_add { $$ = operator("shiftl","<<",5,pair($1,$3)); }
- | exp_sh RSH exp_add { $$ = operator("shiftr",">>",5,pair($1,$3)); }
- | exp_sh RSHU exp_add { $$ = operator("shiftru",">>>",5,pair($1,$3)); }
- ;
- exp_cmp : exp_sh
- | exp_cmp GT exp_sh { $$ = operator("gt",">", 6,pair($1,$3)); }
- | exp_cmp GE exp_sh { $$ = operator("ge",">=",6,pair($1,$3)); }
- | exp_cmp LT exp_sh { $$ = operator("lt","<", 6,pair($1,$3)); }
- | exp_cmp LE exp_sh { $$ = operator("le","<=",6,pair($1,$3)); }
- exp_eq : exp_cmp
- | exp_eq EQ exp_cmp { $$ = operator("eq","==",7,pair($1,$3)); }
- | exp_eq NE exp_cmp { $$ = operator("ne","!=",7,pair($1,$3)); }
- ;
- exp_bitand : exp_eq
- | exp_bitand BITAND exp_eq { $$ = operator("bitand","&",8,pair($1,$3)); }
- ;
- exp_bitor : exp_bitand
- | exp_bitor BITOR exp_bitand { $$ = operator("bitor", "|",9,pair($1,$3)); }
- ;
- exp_logand : exp_bitor
- | exp_logand LOGAND exp_bitor { $$ = operator("and","&&",10,pair($1,$3)); }
- | exp_logand LOGAND2 exp_bitor { $$ = operator("and2","&&&",10,pair($1,$3)); }
- ;
- exp_logor : exp_logand
- | exp_logor LOGOR exp_logand { $$ = operator("or", "||",11,pair($1,$3)); }
- | exp_logor LOGOR2 exp_logand { $$ = operator("or2", "|||",11,pair($1,$3)); }
- ;
- exp_cond : exp_logor
- | exp_logor '?' exp_cond ':' exp_cond
- { $$ = operator("if","?:",12,triple($1,$3,$5)); }
- ;
- exp_let : exp_cond
- | name '=' exp_let { $$ = binding($1,$3); define_variable($$); }
- ;
- exp : exp_let { if (syntax_error_occurred) {syntax_error_occurred = 0; YYERROR; } else $$ = $1; }
- ;
- name : NAME
- | VARNAME
- ;
- %%
- void syntax_error(const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- vfprintf(stderr, fmt, va);
- va_end(va);
- fprintf(stderr, "\n");
- syntax_error_occurred = 1;
- }
- void yyerror(char *s)
- {
- fprintf(stderr, "%s\n", s);
- syntax_error_occurred = 0;
- }
- static expr_list *parse(void)
- {
- #if 0
- yydebug = 1;
- #endif
- syntax_error_occurred = 0;
- if (yyparse() != 0)
- {
- fprintf(stderr, "Parse error\n");
- return NULL;
- }
- if (syntax_error_occurred)
- {
- fprintf(stderr, "Syntax error\n");
- return NULL;
- }
- return result;
- }
- expr_list *parse_string(const char *s)
- {
- initialize_scanner_string(s);
- return parse();
- }
- expr_list *parse_stream(FILE *fp)
- {
- expr_list *e;
- initialize_scanner_stream(fp);
- if (isatty(fileno(fp)))
- fputs("Enter expressions, \"end\" when done.\n", stderr);
- e = parse();
- if (isatty(fileno(fp)))
- fputs("\n", stderr);
- return e;
- }
|