Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / StyleSheet / style.y
1 /* $XConsortium: style.y /main/4 1996/11/11 11:51:33 drk $ */
2
3 %{
4 #include <stdio.h>
5 #include <ctype.h>
6 #include <sstream>
7 #include <iostream.h>
8 #include <assert.h>
9 #include "StyleSheetExceptions.h"
10 #include "VariableTable.h"
11 #include "FeatureValue.h"
12 #include "Expression.h"
13 #include "SSPath.h"
14 #include "PathTable.h"
15 #include "Renderer.h"
16 #include "PathQualifier.h"
17 #include "Debug.h"
18 #include "ParserConst.h"
19 #include "FeatureDefDictionary.h"
20 #include <utility/funcs.h>
21
22 #include "HardCopy/autoNumberFP.h"
23 extern autoNumberFP gAutoNumberFP;
24
25
26 #define alloca(x)       (malloc(x))
27
28 extern void yyerror(char*);
29 extern int yylex();
30
31 extern void enter_sgmlgi_context();
32
33 extern featureDefDictionary* g_FeatureDefDictionary;
34 extern unsigned g_validation_mode;
35 extern unsigned g_hasSemanticError;
36
37 static char localCharToCharPtrBuf[2];
38
39 #undef yywrap
40
41 const char* toUpperCase(unsigned char* string)
42 {
43    static char buffer[512];
44    int j=0;
45    for ( int i=0; i<strlen((const char*)string); i++ ) 
46    {
47                  if (islower(string[i]))
48                    buffer[j] = toupper(string[i]) ;
49                  else
50                    buffer[j] = (char)string[i] ;
51                  j++;
52    }
53    buffer[j] = 0;
54    return buffer;
55 }
56
57 %}
58
59 %union
60 {
61  unsigned char  charData;
62  unsigned char* charPtrData;
63  unsigned int   boolData;
64  int            intData;
65  float          realData;
66  Expression*    expPtrData;
67  TermNode*      termNodePtrData;
68  FeatureValue*  FeatureValuePtrData;
69  FeatureSet*    FeatureSetPtrData;
70  Feature*       FeaturePtrData;
71  SSPath*        PathPtrData;
72  PathTerm*      PathTermPtrData;
73  charPtrDlist*  charPtrDlistData;
74  PathFeatureList* PathFeatureListPtrData;
75  CompositeVariableNode*      CompositeVariableNodePtrData;
76
77  CC_TPtrSlist<FeatureValue>* FeatureValueSlistPtrData;
78
79  PQExpr*        PQExprPtrData;
80 }
81
82 %token<intData>
83         INTEGER
84         OPER_equality
85         OPER_relational
86
87 %token<boolData>
88         BOOLVAL
89
90 %token<realData>
91         REAL
92
93 %token<charData>
94         OPER_assign
95         ARRAYOPEN
96         ARRAYCLOSE
97         SEPARATOR
98         FSOPEN
99         FSCLOSE
100         OPER_modify
101         OPER_parent
102         OPER_attr
103         OPER_oneof
104         OPER_star
105         OPER_or
106         OPER_and
107         OPER_div
108         OPER_parenopen
109         OPER_parenclose
110         OPER_logicalnegate
111         PMEMOPEN
112         PMEMCLOSE
113         OPER_period
114         OPER_plus
115         OPER_minus
116
117 %token<charPtrData>
118         DIMENSION       
119         NORMAL_STRING
120         UNIT_STRING
121         QUOTED_STRING
122         GI_CASE_SENSITIVE
123         SGMLGI_STRING
124
125 %type<intData>
126         POSITION_VALUE
127
128 %type<charPtrData>
129         SGMLGI
130         STRING
131         array_name
132         SGMLGI_CONTENT
133
134 %type<charData>
135         OPER_mult
136         OPER_binop
137         OPER_add
138         OPER_feature
139
140 %type<expPtrData>
141         multi_expr
142         simple_expr
143
144 %type<termNodePtrData>
145         term
146         symbol
147         parent
148         attr
149         dimension
150
151 %type<FeatureSetPtrData>
152         featureset
153         feature_list
154
155 %type<FeatureValuePtrData>
156         rhs.gp
157         array
158         array_member
159
160 %type<CompositeVariableNodePtrData>
161         string_list
162
163 %type<FeatureValueSlistPtrData>
164         array_member_list
165
166 %type<FeaturePtrData>
167         feature
168
169 %type<PathPtrData>
170         path_term_list
171
172 %type<PathTermPtrData>
173         path_term
174
175 %type<PathFeatureListPtrData>
176         path_expr_list
177         path_expr
178
179 %type<charPtrDlistData>
180         feature_name_list
181
182 %type<PQExprPtrData>
183         boolean_expr
184         logical_and_expr
185         equality_expr
186         path_selectorOPTL
187         path_selector
188
189 %start  stylesheet
190
191 %nonassoc OPER_period
192 %nonassoc SGMLGI_STRING
193
194 %%
195
196 stylesheet      : sensitivityOPTL statement.gpOPTL
197         {
198         }
199         ;
200
201 sensitivity     : GI_CASE_SENSITIVE OPER_assign BOOLVAL 
202         {
203           gGI_CASE_SENSITIVE = $3;
204         }
205         ;
206
207 statement.gp    : var_assignment 
208         {
209         }
210         | path_expr 
211         {
212           /* copy items form the feature list into the path table */
213           PathFeatureListIterator l_Iter(*($1));
214
215           PathFeature *x = 0;
216
217           while ( ++l_Iter ) {
218
219             x = l_Iter.key();
220
221             if ( g_validation_mode == true )
222               if ( g_FeatureDefDictionary -> checkSemantics(x -> featureSet()) == false )
223                  g_hasSemanticError = true;
224                
225             gPathTab -> addPathFeatureSet( x );
226
227
228           }
229
230 /* clear out the first list so the elements are not deleted
231              with the list because they are still referenced by the
232              path table */
233
234           $1 -> clear();
235           delete $1;
236
237         }
238         ;
239
240 var_assignment  : STRING OPER_assign rhs.gp 
241         {
242            Expression *x = new Expression(new ConstantNode($3));
243
244            if ( gAutoNumberFP.accept((const char*)$1, x) ) {
245                  delete $1;
246                  delete x;
247                  break;
248            }
249
250            gVariableTable -> enter( gSymTab -> intern((const char*)$1), x);
251            delete $1;
252         }
253         ;
254
255 symbol  : attr
256         {
257           $$=$1;
258         }
259         |
260         parent string_list 
261         {
262           $$=$1;
263         }
264         | string_list
265         {
266           const Symbol* x = $1 -> convertableToVariable();
267           if ( x ) {
268             $$=new VariableNode(*x);
269             delete $1;
270           } else
271             $$=$1;
272         }
273         ;
274
275 string_list : string_list OPER_feature STRING
276         {
277
278           $1->appendItem(gSymTab->intern(toUpperCase($3)));
279           $$=$1;
280           delete $3 ;
281         }
282         | STRING
283         {
284           $$=new CompositeVariableNode;
285           $$ -> appendItem(gSymTab->intern(toUpperCase($1)));
286           delete $1;
287         }
288         ;
289
290 parent  : OPER_parent SGMLGI 
291         {
292 /*
293           $$=new
294             ParentNode(gSymTab->intern((const char*)$1));
295 */
296           MESSAGE(cerr, "^ operator not supported.");
297           throw(StyleSheetException());
298         }
299         ;
300
301 attr    : OPER_attr SGMLGI 
302         {
303           $$=new
304             SgmlAttributeNode(gSymTab->intern((const char*)$2));
305           delete $2;
306         }
307         ;
308
309 rhs.gp  : simple_expr
310         {
311           $$=new FeatureValueExpression($1);
312         }
313         | array 
314         {
315           $$=$1;
316         }
317         | featureset 
318         {
319           $$=new FeatureValueFeatureSet($1);
320         }
321         ;
322
323
324 simple_expr   : simple_expr OPER_add multi_expr 
325         {
326            BinaryOperatorNode::operatorType opType;
327            switch ($2) {
328              case '+': opType=BinaryOperatorNode::PLUS; break;
329              case '-': opType=BinaryOperatorNode::MINUS; break;
330              default:
331               throw(badEvaluationException());
332            }
333
334            FeatureValueExpression* FVexprL = new FeatureValueExpression($1);
335            FeatureValueExpression* FVexprR = new FeatureValueExpression($3);
336            
337            $$ = new Expression(
338                  new BinaryOperatorNode(opType, 
339                                         new ConstantNode(FVexprL),
340                                         new ConstantNode(FVexprR)
341                                        )
342                               );
343         }
344         | multi_expr 
345         {
346            $$=$1;
347         }
348         ;
349
350 multi_expr      : multi_expr OPER_mult term 
351         {
352            BinaryOperatorNode::operatorType opType;
353            switch ($2) {
354              case '*': opType=BinaryOperatorNode::TIMES; break;
355              case '/': opType=BinaryOperatorNode::DIVIDE; break;
356              default:
357               throw(badEvaluationException());
358            }
359
360            FeatureValueExpression* FVexpr = new FeatureValueExpression($1);
361            
362            $$ = new Expression(
363                  new BinaryOperatorNode(opType, new ConstantNode(FVexpr), $3)
364                               );
365         }
366         | term
367         {
368            $$ = new Expression($1);
369         }
370         ;
371
372 OPER_binop : OPER_mult
373         {
374            $$=$1;
375         }
376         | OPER_add
377         {
378            $$=$1;
379         }
380         ;
381
382 OPER_mult       : OPER_star
383         {
384            $$=$1;
385         }
386         | OPER_div
387         {
388            $$=$1;
389         }
390         ;
391
392 term    : BOOLVAL
393         {
394           $$=new ConstantNode(new FeatureValueInt(int($1)));
395         }
396         | symbol UNIT_STRING
397         {
398           FeatureValueExpression* fve = 
399                 new FeatureValueExpression(new Expression($1));
400           FeatureValueDimension* x = 
401              new FeatureValueDimension(fve, (const char*)$2);
402           delete $2 ;
403           $$=new ConstantNode(x);
404         }
405         | symbol
406         {
407           $$=$1;
408         }
409         | dimension 
410         {
411           $$=$1;
412         }
413         | QUOTED_STRING
414         {
415           $$=new ConstantNode(new FeatureValueString((const char*)$1));
416           delete $1 ;
417         }
418         | INTEGER UNIT_STRING
419         {
420           $$=new ConstantNode(new FeatureValueDimension(new FeatureValueInt($1), (const char*)$2));
421           delete $2 ;
422         }
423         | REAL UNIT_STRING
424         {
425           $$=new ConstantNode(new FeatureValueDimension(new FeatureValueReal($1), (const char*)$2));
426           delete $2 ;
427         }
428         | INTEGER
429         {
430           $$=new ConstantNode(new FeatureValueInt($1));
431         }
432         | REAL
433         {
434           $$=new ConstantNode(new FeatureValueReal($1));
435         }
436         | OPER_parenopen simple_expr OPER_parenclose
437         {
438           $$=new ConstantNode(new FeatureValueExpression($2));
439         }
440         ;
441
442 array   : array_name ARRAYOPEN array_member_list ARRAYCLOSE 
443         {
444           FeatureValueArray* x = 
445              new FeatureValueArray((const char*)$1, $3 -> entries());
446           CC_TPtrSlistIterator<FeatureValue> iter(*$3);
447
448           int i = 0;
449           while ( ++iter ) {
450             (*x)[i++] = iter.key();
451           }
452
453           delete $1;
454           delete $3;
455
456           $$ = x;
457         }
458         | array_name ARRAYOPEN ARRAYCLOSE
459         {
460           $$ = new FeatureValueArray((const char*)$1, 0);
461           delete $1;
462         }
463         ;
464
465 array_name : STRING
466         {
467           $$ = $1;
468         }
469         |
470         {
471           $$ = new unsigned char[1];
472           $$[0] = 0;
473         }
474         ;
475
476 array_member_list       : array_member SEPARATOR array_member_list
477         {
478            $3 -> prepend($1);
479            $$ = $3;
480         }
481         | array_member  
482         {
483            $$=new CC_TPtrSlist<FeatureValue>;
484            $$ -> append($1);
485         }
486         ;
487
488 array_member : simple_expr
489         {
490            $$ = new FeatureValueExpression($1);
491         }
492         | array
493         {
494            $$=$1;
495         }
496         ;
497
498 featureset      : FSOPEN feature_list SEPARATOR_OPTL FSCLOSE 
499         {
500            $$=$2;
501         }
502         | FSOPEN FSCLOSE
503         {
504           $$ = new FeatureSet ();
505         }
506         ;
507
508 feature_list    : feature_list SEPARATOR feature 
509         {
510            if ($3 -> name() == Symbol(gSymTab->intern("FAMILY"))) {
511              // the evaluate() call clones $3 
512              FeatureValueFeatureSet *fvfs = 
513                (FeatureValueFeatureSet*) $3->evaluate();
514              const FeatureSet* fs = fvfs->value();
515               const Feature* charsetF =
516                 fs->lookup(gSymTab->intern("CHARSET"));
517               // charsetF is a mandatory entry in fontfamily
518               assert( charsetF );
519               const FeatureValueString* fv_string =
520                         (FeatureValueString*)charsetF->value();
521               const char* charset = *fv_string;
522               assert( charset );
523               
524               int entries = $1 -> entries();
525               for (int i=0; i<entries; i++) {
526                 const Feature* entry = $1->at(i);
527                 if (! (entry->name() == Symbol(gSymTab->intern("FAMILY"))))
528                   continue;
529                 const FeatureSet* entry_fs =
530                         ((FeatureValueFeatureSet*)(entry->evaluate()))->value();
531                 const Feature* entry_charsetF =
532                         entry_fs->lookup(gSymTab->intern("CHARSET"));
533                 assert( entry_charsetF );
534                 const char* entry_charset =
535                         *((FeatureValueString*)(entry_charsetF->value()));
536                 assert( entry_charset );
537                 if (! strcmp(charset, entry_charset)) {
538                   delete $1 -> removeAt(i);
539                   break; // escape from for-loop
540                 }
541               }
542               delete fvfs ;
543
544               $$ = $1;
545               $$ -> add($3);
546            }
547            else {
548               if ( $1 -> find((Feature*)$3) ) {
549                 FeatureSet* fs = new FeatureSet();
550                 fs -> add($3);
551
552                 $$ =new FeatureSet(*$1, *fs);
553                 delete $1;
554                 delete fs;
555               }
556               else {
557                 $$=$1;
558                 $$ -> add($3);
559               }
560            }
561         }
562         | feature 
563         {
564            $$=new FeatureSet();
565            $$ -> add($1);
566         }
567         ;
568
569 SEPARATOR_OPTL : SEPARATOR
570         {
571         }
572         |
573         {
574         }
575         ;
576
577 feature         : feature_name_list OPER_modify rhs.gp
578         {
579           CC_TPtrDlistIterator<char> l_Iter(*($1));
580
581           FeatureSet *fs = 0;
582           Feature *f = 0;
583           FeatureValue *fv = $3;
584           const char* cptr = 0;
585           char buffer[256];
586           while (++l_Iter) {
587              cptr = l_Iter.key();
588              int index = 0 ;
589              const char *c = cptr ;
590              while (*c)
591                {
592                  if (islower(*c))
593                    buffer[index] = toupper(*c) ;
594                  else
595                    buffer[index] = *c ;
596                  c++ ;
597                  index++;
598                }
599              buffer[index] = 0;
600              /* fprintf(stderr, "converted: %s to %s\n", cptr, buffer); */
601              f = new Feature(gSymTab -> intern(buffer), fv);
602
603              if ( $1 -> last() != cptr ) {
604                 fs = new FeatureSet();
605                 fs -> add(f);
606                 fv = new FeatureValueFeatureSet(fs);
607              }
608           }
609
610           $1->clearAndDestroy();
611           delete $1 ;
612           $$=f;
613         }
614         ;
615
616 feature_name_list       : feature_name_list OPER_feature STRING
617         {
618           $1 -> prepend((char *)$3);
619           $$=$1;
620         }
621         |
622         STRING
623         {
624           $$=new CC_TPtrDlist<char>;
625           $$ -> append((char *)$1);
626         }
627         ;
628
629 path_expr       : path_term_list featureset
630         {
631            $$=new PathFeatureList;
632            $$ -> append(new PathFeature($1, $2));
633         }
634         | path_term_list OPER_parenopen path_expr_list OPER_parenclose 
635         {
636           
637           PathFeatureListIterator l_Iter(*($3));
638
639           while ( ++l_Iter ) {
640              (l_Iter.key()) -> path() -> prependPath(*$1);
641           }
642           delete $1;
643           $$=$3;
644         }
645         ;
646
647 path_expr_list :        path_expr_list SEPARATOR path_expr
648         {
649            $$=$1;
650            $$ -> appendList(*$3);
651            delete $3 ;
652         }
653         | path_expr
654         {
655            $$=$1;
656         }
657
658 path_term_list : path_term_list path_term  
659         {
660           $1 -> appendPathTerm($2);
661           $$=$1;
662         }
663         | path_term
664         {
665           $$ = new SSPath;
666           $$ -> appendPathTerm($1);
667         }
668         ;
669
670 path_term : SGMLGI path_selectorOPTL 
671         {
672           $$=new PathTerm((const char*)$1, $2);
673           delete $1;
674         }
675         | OPER_oneof 
676         {
677           localCharToCharPtrBuf[0]=$1; localCharToCharPtrBuf[1]=0;
678           $$=new PathTerm(localCharToCharPtrBuf, 0);
679         }
680         | OPER_star 
681         {
682           localCharToCharPtrBuf[0]=$1; localCharToCharPtrBuf[1]=0;
683           $$=new PathTerm(localCharToCharPtrBuf, 0);
684         }
685         ;
686
687 OPER_feature : OPER_period
688         {
689         }
690
691 OPER_add : OPER_plus
692         {
693         }
694         | OPER_minus
695         {
696         }
697         ;
698
699 SGMLGI : SGMLGI_CONTENT
700         {
701         // char % can start an OLIAS internal element which
702         // is used only by the browser.
703         // Example %BOGUS within HEAD1 in OLIAS book
704
705            if ( $1[0] != '%' && isalnum($1[0]) == 0 ) {
706               MESSAGE(cerr, form("%s is not a SGMLGI", $1));
707               throw(badEvaluationException());
708            }
709           /* note, should probably be using RCStrings, would make wide */
710           /* char handling better too? */
711            if ( gGI_CASE_SENSITIVE == false )
712              {
713                for (int i=0; i<strlen((const char*)$1); i++)
714                  if ( islower($1[i]) )
715                    $1[i] = toupper($1[i]);
716              }
717            $$=$1;
718         }
719         ;
720
721 SGMLGI_CONTENT : STRING OPER_period {enter_sgmlgi_context();} SGMLGI_STRING 
722         {
723            int l = strlen((char*)$1) + strlen((char*)$4) + 2;
724            $$=new unsigned char[l];
725            strcpy((char*)$$, (char*)$1);
726            strcat((char*)$$, ".");
727            strcat((char*)$$, (char*)$4);
728            delete $1;
729            delete $4;
730         }
731         | STRING OPER_period
732         {
733            int l = strlen((char*)$1) + 2;
734            $$=new unsigned char[l];
735            strcpy((char*)$$, (char*)$1);
736            strcat((char*)$$, ".");
737            delete $1;
738         }
739
740         | STRING
741         {
742            $$=$1;
743         }
744         ;
745
746 dimension : DIMENSION
747         {
748           int i;
749
750           for (i=0; i<strlen((const char*)$1); i++) {
751
752             if ( isalpha($1[i]) ) 
753                break;
754           }
755
756           char c;
757           float x;
758           if ( i > 0 ) {
759              c = $1[i]; $1[i]=0;
760              x = atof((const char*)$1);
761              $1[i]=c;
762           } else
763              x = 1;
764
765           $$=new ConstantNode(new FeatureValueDimension(new FeatureValueReal(x), (const char*)&$1[i]));
766
767           delete $1;
768         }
769
770 STRING  : NORMAL_STRING
771         {
772            $$=$1;
773         }
774         | UNIT_STRING
775         {
776            $$=$1;
777         }
778         ;
779
780 path_selector   : ARRAYOPEN boolean_expr ARRAYCLOSE 
781         {
782            $$=$2;
783         }
784         ;
785
786 boolean_expr    : logical_and_expr 
787         {
788 //////////////////////////////////////////////////////
789 // This portion of the code (up to equality_expr) is 
790 // hacked for V1.1 only. Due to the way 
791 // PathQualifier.h is written, this code is not 
792 // general at all. qfc 8/16/94
793 //////////////////////////////////////////////////////
794            $$=$1;
795         }
796         | boolean_expr OPER_or logical_and_expr 
797         {
798            $$ = new PQLogExpr($1, PQor, $3);
799         }
800         ;
801
802 logical_and_expr        : equality_expr 
803         {
804            $$=$1;
805         }
806         | logical_and_expr OPER_and equality_expr 
807         {
808            $$ = new PQLogExpr($1, PQand, $3);
809         }
810         ;
811
812 equality_expr   : OPER_attr SGMLGI OPER_equality QUOTED_STRING
813         {
814           $$ = new PQAttributeSelector(
815                         gSymTab->intern((const char*)$2),
816                         ( $3 == EQUAL ) ? PQEqual : PQNotEqual,
817                         (const char*)$4
818                                       );
819           delete $2;
820           delete $4;
821         }
822         | NORMAL_STRING OPER_equality POSITION_VALUE
823         {
824            if ( strcasecmp((char*)$1, "position") == 0 ) {
825              $$=new PQPosition(
826                   ( $2 == EQUAL ) ? PQEqual : PQNotEqual, 
827                   $3
828                                 );
829            } else
830            if ( strcasecmp((char*)$1, "sibling") == 0 ) {
831              $$=new PQSibling(
832                   ( $2 == EQUAL ) ? PQEqual : PQNotEqual, 
833                   $3
834                                 );
835            } else
836               throw(StyleSheetException());
837
838            delete $1;
839         }
840         ;
841
842 POSITION_VALUE : INTEGER
843         {
844            $$ = (int)$1;
845         }
846         | QUOTED_STRING
847         {
848            if ( strcasecmp((char*)$1, "#LAST") != 0 ) 
849               throw(StyleSheetException());
850
851            $$ = -1;
852         }
853         ;
854
855
856 sensitivityOPTL : sensitivity
857         {
858
859         }
860         | /* empty */
861         {
862
863         }
864         ;
865
866 statement.gpOPTL : statement.gpPLUS
867         {
868         }
869         | /* empty */
870         {
871         }
872         ;
873
874 statement.gpPLUS        : statement.gpPLUS statement.gp
875         {
876
877         }
878         | statement.gp
879         {
880
881         }
882         ;
883
884 path_selectorOPTL       : path_selector
885         {
886           $$=$1;
887         }
888         | /* empty */
889         {
890           $$=0;
891         }
892         ;
893