Subversion Repositories filter_foundry

Rev

Rev 198 | Rev 492 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 198 Rev 358
Line 1... Line 1...
1
%{
1
%{
2
 
2
 
3
/*
3
/*
4
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
4
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
5
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
5
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
6
    Copyright (C) 2018-2019 Daniel Marschall, ViaThinkSoft
6
    Copyright (C) 2018-2019 Daniel Marschall, ViaThinkSoft
7
 
7
 
8
    This program is free software; you can redistribute it and/or modify
8
    This program is free software; you can redistribute it and/or modify
9
    it under the terms of the GNU General Public License as published by  
9
    it under the terms of the GNU General Public License as published by  
10
    the Free Software Foundation; either version 2 of the License, or
10
    the Free Software Foundation; either version 2 of the License, or
11
    (at your option) any later version.
11
    (at your option) any later version.
12
 
12
 
13
    This program is distributed in the hope that it will be useful,
13
    This program is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
    GNU General Public License for more details.
16
    GNU General Public License for more details.
17
 
17
 
18
    You should have received a copy of the GNU General Public License  
18
    You should have received a copy of the GNU General Public License  
19
    along with this program; if not, write to the Free Software
19
    along with this program; if not, write to the Free Software
20
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
*/
21
*/
22
 
22
 
23
#include <stdio.h>
23
#include <stdio.h>
24
#include <string.h>
24
#include <string.h>
25
 
25
 
26
#ifndef false
26
#ifndef false
27
#define false 0
27
#define false 0
28
#define true 1
28
#define true 1
29
#endif
29
#endif
30
 
30
 
31
#include "node.h"
31
#include "node.h"
32
#include "y.tab.h"
32
#include "y.tab.h"
33
 
33
 
34
//#ifdef MAC_ENV
34
//#ifdef MAC_ENV
35
int yyparse(void);
35
int yyparse(void);
36
int yylex(void); // hack. correct prototype is buried in lex output
36
int yylex(void); // hack. correct prototype is buried in lex output
37
//#endif
37
//#endif
38
void yyerror(char*);
38
void yyerror(char*);
39
int pushflag(int x);
39
int pushflag(int x);
40
struct node *parseexpr(char *s);
40
struct node *parseexpr(char *s);
41
 
41
 
42
#define DPARSE 
42
#define DPARSE 
43
 
43
 
44
struct node *parsetree;
44
struct node *parsetree;
45
char *errstr;
45
char *errstr;
46
 
46
 
47
enum{ PARENSTACK = 100 };
47
enum{ PARENSTACK = 100 };
48
 
48
 
49
int inarglist[PARENSTACK],arglistptr; // keep track of whether a comma is an function argument separator, or operator
49
int inarglist[PARENSTACK],arglistptr; // keep track of whether a comma is an function argument separator, or operator
50
 
50
 
51
int pushflag(int x){
51
int pushflag(int x){
52
	if(arglistptr < (PARENSTACK-1))
52
	if(arglistptr < (PARENSTACK-1))
53
		inarglist[++arglistptr] = x;
53
		inarglist[++arglistptr] = x;
54
	else{
54
	else{
55
		yyerror(_strdup("too many nested parentheses or function calls"));
55
		yyerror(_strdup("too many nested parentheses or function calls"));
56
		return true;
56
		return true;
57
	}
57
	}
58
	return false;
58
	return false;
59
}
59
}
60
 
60
 
61
#define POP() --arglistptr
61
#define POP() --arglistptr
62
 
62
 
63
#define ENTERARGS() if(pushflag(true)) YYERROR
63
#define ENTERARGS() if(pushflag(true)) YYERROR
64
#define ENTERPAREN() if(pushflag(false)) YYERROR
64
#define ENTERPAREN() if(pushflag(false)) YYERROR
65
#define LEAVEARGS POP
65
#define LEAVEARGS POP
66
#define LEAVEPAREN POP
66
#define LEAVEPAREN POP
67
 
67
 
68
%}
68
%}
69
 
69
 
70
%token TOK_NUM TOK_EOF TOK_ARGSEP
70
%token TOK_NUM TOK_EOF TOK_ARGSEP
71
%token TOK_FN1 TOK_FN2 TOK_FN3 TOK_FN4 TOK_FN5 TOK_FN10
71
%token TOK_FN1 TOK_FN2 TOK_FN3 TOK_FN4 TOK_FN5 TOK_FN10
72
%token TOK_SPECIALVAR TOK_VAR TOK_UNKNOWN TOK_BADCHAR
72
%token TOK_SPECIALVAR TOK_VAR TOK_UNKNOWN TOK_BADCHAR
73
 
73
 
74
%left ','
74
%left ','
75
%right '?' ':'
75
%right '?' ':'
76
%left LOGAND LOGOR
76
%left LOGAND LOGOR
77
%left '&' '^' '|'
77
%left '&' '^' '|'
78
%left EQ NE
78
%left EQ NE
79
%left '<' LE '>' GE
79
%left '<' LE '>' GE
80
%left SHLEFT SHRIGHT
80
%left SHLEFT SHRIGHT
81
%left '-' '+'
81
%left '-' '+'
82
%left '*' '/' '%'
82
%left '*' '/' '%'
83
%right EXP
83
%right EXP
84
%left NEG 
84
%left NEG 
85
 
85
 
86
%%
86
%%
87
 
87
 
88
input : expr { parsetree = $1; } ;
88
input : expr { parsetree = $1; } ;
89
 
89
 
90
expr : TOK_NUM 
90
expr : TOK_NUM 
91
	| TOK_VAR
91
	| TOK_VAR
92
	| TOK_SPECIALVAR
92
	| TOK_SPECIALVAR
93
	| TOK_FN1 '(' {ENTERARGS();} expr ')' {LEAVEARGS();}
93
	| TOK_FN1 '(' {ENTERARGS();} expr ')' {LEAVEARGS();}
94
		{ $$ = $1; $$->child[0] = $4; }
94
		{ $$ = $1; $$->child[0] = $4; }
95
	| TOK_FN2 '(' {ENTERARGS();} expr TOK_ARGSEP expr ')' {LEAVEARGS();}
95
	| TOK_FN2 '(' {ENTERARGS();} expr TOK_ARGSEP expr ')' {LEAVEARGS();}
96
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; }
96
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; }
97
	| TOK_FN3 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
97
	| TOK_FN3 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
98
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; }
98
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; }
99
	| TOK_FN4 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
99
	| TOK_FN4 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
100
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; $$->child[3] = $10; }
100
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; $$->child[3] = $10; }
101
	| TOK_FN5 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
101
	| TOK_FN5 '(' {ENTERARGS();} expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr ')' {LEAVEARGS();}
102
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; $$->child[3] = $10; $$->child[4] = $12; }
102
		{ $$ = $1; $$->child[0] = $4; $$->child[1] = $6; $$->child[2] = $8; $$->child[3] = $10; $$->child[4] = $12; }
103
	| TOK_FN10 '(' {ENTERARGS();} 
103
	| TOK_FN10 '(' {ENTERARGS();} 
104
			expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP
104
			expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP
105
			expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr
105
			expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr TOK_ARGSEP expr
106
			')' {LEAVEARGS();}
106
			')' {LEAVEARGS();}
107
		{ $$ = $1; 
107
		{ $$ = $1; 
108
			$$->child[0] = $4;  $$->child[1] = $6;  $$->child[2] = $8;  $$->child[3] = $10; $$->child[4] = $12;
108
			$$->child[0] = $4;  $$->child[1] = $6;  $$->child[2] = $8;  $$->child[3] = $10; $$->child[4] = $12;
109
			$$->child[5] = $14; $$->child[6] = $16; $$->child[7] = $18; $$->child[8] = $20; $$->child[9] = $22; 
109
			$$->child[5] = $14; $$->child[6] = $16; $$->child[7] = $18; $$->child[8] = $20; $$->child[9] = $22; 
110
		}
110
		}
111
	| '(' {ENTERPAREN();} expr ')' { LEAVEPAREN(); $$ = $3; }
111
	| '(' {ENTERPAREN();} expr ')' { LEAVEPAREN(); $$ = $3; }
112
/* arithmetic operators */
112
/* arithmetic operators */
113
	| expr '+' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
113
	| expr '+' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
114
	| expr '-' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
114
	| expr '-' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
115
	| expr '*' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
115
	| expr '*' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
116
	| expr '/' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
116
	| expr '/' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
117
	| expr '%' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
117
	| expr '%' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
118
/* exponentiation (not in FF spec) */
118
/* exponentiation (not in FF spec) */
119
	| expr EXP expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
119
	| expr EXP expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
120
/* relational operators */
120
/* relational operators */
121
	| expr EQ expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
121
	| expr EQ expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
122
	| expr NE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
122
	| expr NE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
123
	| expr '<' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
123
	| expr '<' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
124
	| expr LE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
124
	| expr LE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
125
	| expr '>' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
125
	| expr '>' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
126
	| expr GE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
126
	| expr GE expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
127
/* logical operators */
127
/* logical operators */
128
	| expr LOGAND expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
128
	| expr LOGAND expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
129
	| expr LOGOR expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
129
	| expr LOGOR expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
130
	| '!' expr %prec NEG { $$ = $1; $$->child[0] = $2; }
130
	| '!' expr %prec NEG { $$ = $1; $$->child[0] = $2; }
131
/* conditional operator */
131
/* conditional operator */
132
	| expr '?' expr ':' expr
132
	| expr '?' expr ':' expr
133
		{ $$ = $2; $$->child[0] = $1; $$->child[1] = $3; $$->child[2] = $5; }
133
		{ $$ = $2; $$->child[0] = $1; $$->child[1] = $3; $$->child[2] = $5; }
134
/* bitwise operators */
134
/* bitwise operators */
135
	| expr '&' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
135
	| expr '&' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
136
	| expr '^' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
136
	| expr '^' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
137
	| expr '|' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
137
	| expr '|' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
138
	| expr SHLEFT expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
138
	| expr SHLEFT expr  { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
139
	| expr SHRIGHT expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
139
	| expr SHRIGHT expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
140
	| '~' expr %prec NEG { $$ = $1; $$->child[0] = $2; }
140
	| '~' expr %prec NEG { $$ = $1; $$->child[0] = $2; }
141
/* sequence operator */
141
/* sequence operator */
142
	| expr ',' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
142
	| expr ',' expr { $$ = $2; $$->child[0] = $1; $$->child[1] = $3; }
143
/* unary operators */
143
/* unary operators */
144
	| '-' expr %prec NEG { $$ = $1; $$->child[0] = 0; $$->child[1] = $2; }
144
	| '-' expr %prec NEG { $$ = $1; $$->child[0] = 0; $$->child[1] = $2; }
145
	| '+' expr %prec NEG { $$ = $2; }
145
	| '+' expr %prec NEG { $$ = $2; }
146
/* error tokens */
146
/* error tokens */
147
	| TOK_UNKNOWN { yyerror(_strdup("unknown name")); YYERROR; }
147
	| TOK_UNKNOWN { yyerror(_strdup("unknown name")); YYERROR; }
148
	| TOK_BADCHAR { yyerror(_strdup("disallowed character")); YYERROR; }
148
	| TOK_BADCHAR { yyerror(_strdup("disallowed character")); YYERROR; }
149
	;
149
	;
150
 
150
 
151
%%
151
%%
152
 
152
 
153
// Daniel 06 July 2021: Move these two lines out of the function parseexpr(), otherwise the code won't compile in G++
153
// Daniel 06 July 2021: Move these two lines out of the function parseexpr(), otherwise the code won't compile in G++
154
struct yy_buffer_state *yy_scan_string(const char*); // hack. correct prototype is buried in lex output
154
struct yy_buffer_state *yy_scan_string(const char*); // hack. correct prototype is buried in lex output
155
int yyparse(void); // hack. correct prototype appears just after this code, in yacc output
155
int yyparse(void); // hack. correct prototype appears just after this code, in yacc output
156
 
156
 
157
struct node *parseexpr(char *s){
157
struct node *parseexpr(char *s){
158
	extern int tokpos,tokstart;
158
	extern int tokpos,tokstart;
159
	
159
	
160
	tokstart = tokpos = 0;
160
	tokstart = tokpos = 0;
161
 
161
 
162
	if(s){
162
	if(s){
163
		arglistptr = 0;
163
		arglistptr = 0;
164
		inarglist[arglistptr] = false;
164
		inarglist[arglistptr] = false;
165
	
165
	
166
		node_list = 0;
166
		node_list = 0;
167
		yy_scan_string(s);
167
		yy_scan_string(s);
168
	
168
	
169
		if(!yyparse())
169
		if(!yyparse())
170
			return parsetree;
170
			return parsetree;
171
		else /* ensure we don't leak memory, on an unsuccessful parse */
171
		else /* ensure we don't leak memory, on an unsuccessful parse */
172
			freeallnodes();
172
			freeallnodes();
173
	}else
173
	}else
174
		yyerror(_strdup("null string???"));
174
		yyerror(_strdup("null string???"));
175
	return 0;
175
	return 0;
176
}
176
}
177
 
177
 
178
void yyerror(char *msg){
178
void yyerror(char *msg){
179
	errstr = msg;
179
	errstr = msg;
180
}
180
}