Subversion Repositories filter_foundry

Rev

Rev 198 | Rev 492 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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