Subversion Repositories filter_foundry

Rev

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

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