4 Cassowary Incremental Constraint Solver
5 Original Smalltalk Implementation by Alan Borning
6 This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
7 http://www.cs.washington.edu/homes/gjb
8 (C) 1998, 1999 Greg J. Badros and Alan Borning
9 See ../LICENSE for legal details regarding this software
12 Original implementation contributed by Steve Wolfman
13 Subsequently largely revised by Greg J. Badros
15 Supports parsing of read-only variables in constraints via "?" suffix
16 annotations on variables. If a variable is followed by "?" in any of
17 its occurrences in the constraint, that variable is deemed read-only
18 and entered into the constraint object as such. E.g.,
22 is a one-way constraint that sets x from y's value.
28 are identical one-way constraints with y read-only. One would prefer
29 to have it written like so:
33 but it need not be, and no warning or error is raised.
40 #include <cassowary/Cl.h>
46 #define CONFIG_H_INCLUDED
49 #ifdef USE_CRUMMY_LEXER
50 string current; /* Global to help in debugging/error messages */
53 /* Get yyparse, yylex to have an extra argument (type void *) */
54 #define YYPARSE_PARAM cl_parse_data
55 #define YYLEX_PARAM cl_parse_data
56 #ifndef YYERROR_VERBOSE
57 #define YYERROR_VERBOSE
64 /* Bison Declarations */
70 const ClVariable *pclv;
71 ClLinearExpression *pcle;
76 int yylex(YYSTYPE *lvalp, void *YYLEX_PARAM);
77 void yyerror(const char *sz);
92 %type <pcn> constraint equation inequality
101 constraint: equation { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
102 | inequality { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
105 equation: expr '=' expr { $$ = new ClLinearEquation(*$1, *$3); }
108 inequality: expr GEQ expr { $$ = new ClLinearInequality(*$1, cnGEQ, *$3); }
109 | expr LEQ expr { $$ = new ClLinearInequality(*$1, cnLEQ, *$3); }
110 | expr LT expr { $$ = new ClLinearInequality(*$1, cnLT, *$3); }
111 | expr GT expr { $$ = new ClLinearInequality(*$1, cnGT, *$3); }
114 expr: NUM { $$ = new ClLinearExpression($1); }
115 | VAR { $$ = new ClLinearExpression(*$1); }
116 | RO_VAR { $$ = new ClLinearExpression(*$1);
117 ((ClParseData*)YYPARSE_PARAM)->_readOnlyVarsSoFar.insert(*$1); }
118 | expr '+' expr { $$ = new ClLinearExpression(*$1 + *$3); }
119 | expr '-' expr { $$ = new ClLinearExpression(*$1 - *$3); }
120 | expr '*' expr { $$ = new ClLinearExpression(*$1 * *$3); }
121 | expr '/' expr { $$ = new ClLinearExpression(*$1 / *$3); }
122 | '-' expr %prec NEG { $$ = new ClLinearExpression(-1 * *$2); }
123 | '(' expr ')' { $$ = $2; }
128 void clerror(const char *sz)
130 throw ExCLParseErrorMisc(sz);
133 extern istream *pxi_lexer;
135 // xi is the stream from which to read the constraint.
136 // aVars is an array of variables large enough to account for
137 // each one that might be mentioned in a constraint
138 ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func,
139 const ClStrength &strength)
141 ClParseData cl_parse_data(xi, lookup_func);
143 if (yyparse(&cl_parse_data) == 0) { // success
145 cerr << *cl_parse_data.Pcn() << endl;
147 cl_parse_data.Pcn()->ChangeStrength(strength);
148 cl_parse_data.Pcn()->AddROVars(cl_parse_data._readOnlyVarsSoFar);
149 return cl_parse_data.Pcn();