13
0
livetrax/libs/cassowary/ClReader.yy

155 lines
3.8 KiB
Plaintext
Raw Normal View History

/*
$Id$
Cassowary Incremental Constraint Solver
Original Smalltalk Implementation by Alan Borning
This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
http://www.cs.washington.edu/homes/gjb
(C) 1998, 1999 Greg J. Badros and Alan Borning
See ../LICENSE for legal details regarding this software
ClReader.y
Original implementation contributed by Steve Wolfman
Subsequently largely revised by Greg J. Badros
Supports parsing of read-only variables in constraints via "?" suffix
annotations on variables. If a variable is followed by "?" in any of
its occurrences in the constraint, that variable is deemed read-only
and entered into the constraint object as such. E.g.,
x = 2*y?
is a one-way constraint that sets x from y's value.
x = y + y?
and
x = y? + y
are identical one-way constraints with y read-only. One would prefer
to have it written like so:
x = y? + y?
but it need not be, and no warning or error is raised.
*/
%{
/* C Declarations */
#include <cassowary/Cl.h>
#include <string>
#include <map>
#ifdef HAVE_CONFIG_H
#include <config.h>
#define CONFIG_H_INCLUDED
#endif
#ifdef USE_CRUMMY_LEXER
string current; /* Global to help in debugging/error messages */
#endif
/* Get yyparse, yylex to have an extra argument (type void *) */
#define YYPARSE_PARAM cl_parse_data
#define YYLEX_PARAM cl_parse_data
#ifndef YYERROR_VERBOSE
#define YYERROR_VERBOSE
#endif
#define YYDEBUG 1
%}
/* Bison Declarations */
%pure_parser
%union {
double num;
const ClVariable *pclv;
ClLinearExpression *pcle;
ClConstraint *pcn;
}
%{
int yylex(YYSTYPE *lvalp, void *YYLEX_PARAM);
void yyerror(const char *sz);
%}
%start constraint
%token <num> NUM
%token <pclv> VAR
%token <pclv> RO_VAR
%token GEQ
%token GT
%token LEQ
%token LT
%type <pcle> expr
%type <pcn> constraint equation inequality
%left '-' '+'
%left '*' '/'
%left NEG
%%
/* Grammar Rules */
constraint: equation { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
| inequality { $$ = $1; ((ClParseData*)YYPARSE_PARAM)->_pcn = $1; }
;
equation: expr '=' expr { $$ = new ClLinearEquation(*$1, *$3); }
;
inequality: expr GEQ expr { $$ = new ClLinearInequality(*$1, cnGEQ, *$3); }
| expr LEQ expr { $$ = new ClLinearInequality(*$1, cnLEQ, *$3); }
| expr LT expr { $$ = new ClLinearInequality(*$1, cnLT, *$3); }
| expr GT expr { $$ = new ClLinearInequality(*$1, cnGT, *$3); }
;
expr: NUM { $$ = new ClLinearExpression($1); }
| VAR { $$ = new ClLinearExpression(*$1); }
| RO_VAR { $$ = new ClLinearExpression(*$1);
((ClParseData*)YYPARSE_PARAM)->_readOnlyVarsSoFar.insert(*$1); }
| expr '+' expr { $$ = new ClLinearExpression(*$1 + *$3); }
| expr '-' expr { $$ = new ClLinearExpression(*$1 - *$3); }
| expr '*' expr { $$ = new ClLinearExpression(*$1 * *$3); }
| expr '/' expr { $$ = new ClLinearExpression(*$1 / *$3); }
| '-' expr %prec NEG { $$ = new ClLinearExpression(-1 * *$2); }
| '(' expr ')' { $$ = $2; }
;
%%
void clerror(const char *sz)
{
throw ExCLParseErrorMisc(sz);
}
extern istream *pxi_lexer;
// xi is the stream from which to read the constraint.
// aVars is an array of variables large enough to account for
// each one that might be mentioned in a constraint
ClConstraint *PcnParseConstraint(istream &xi, const ClVarLookupFunction &lookup_func,
const ClStrength &strength)
{
ClParseData cl_parse_data(xi, lookup_func);
pxi_lexer = &xi;
if (yyparse(&cl_parse_data) == 0) { // success
#ifdef DEBUG_PARSER
cerr << *cl_parse_data.Pcn() << endl;
#endif
cl_parse_data.Pcn()->ChangeStrength(strength);
cl_parse_data.Pcn()->AddROVars(cl_parse_data._readOnlyVarsSoFar);
return cl_parse_data.Pcn();
}
else { // failed
return 0;
}
}