Root/fpd.y

Source at commit 190bcaf982869388b508a0a4c97cff62fbb73038 created 9 years 2 months ago.
By werner, Added a topological sort algorithm, for use when dumping.
1%{
2/*
3 * fpd.y - FootPrint Definition language
4 *
5 * Written 2009, 2010 by Werner Almesberger
6 * Copyright 2009, 2010 by Werner Almesberger
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
14
15#include <stdlib.h>
16#include <string.h>
17
18#include "util.h"
19#include "error.h"
20#include "expr.h"
21#include "obj.h"
22#include "meas.h"
23#include "gui_status.h"
24#include "dump.h"
25#include "tsort.h"
26#include "fpd.h"
27
28
29struct expr *expr_result;
30const char *var_id;
31struct value *var_value_list;
32
33
34static struct frame *curr_frame;
35static struct table *curr_table;
36static struct row *curr_row;
37
38static struct frame *last_frame = NULL;
39static struct vec *last_vec = NULL;
40
41static struct table **next_table;
42static struct loop **next_loop;
43static struct vec **next_vec;
44static struct obj **next_obj;
45
46static int n_vars, n_values;
47
48static const char *id_sin, *id_cos, *id_sqrt;
49
50static struct tsort *tsort;
51
52
53static struct frame *find_frame(const char *name)
54{
55    struct frame *f;
56
57    for (f = frames; f; f = f->next)
58        if (f->name == name)
59            return f;
60    return NULL;
61}
62
63
64static struct vec *find_vec(const struct frame *frame, const char *name)
65{
66    struct vec *v;
67
68    for (v = frame->vecs; v; v = v->next)
69        if (v->name == name)
70            return v;
71    return NULL;
72}
73
74
75static struct obj *find_obj(const struct frame *frame, const char *name)
76{
77    struct obj *obj;
78
79    for (obj = frame->objs; obj; obj = obj->next)
80        if (obj->name == name)
81            return obj;
82    return NULL;
83}
84
85
86static int find_label(const struct frame *frame, const char *name)
87{
88    if (find_vec(frame, name))
89        return 1;
90    if (find_obj(frame, name))
91        return 1;
92    return 0;
93}
94
95
96static struct var *find_var(const struct frame *frame, const char *name)
97{
98    const struct table *table;
99    struct var *var;
100    struct loop *loop;
101
102    for (table = frame->tables; table; table = table->next)
103        for (var = table->vars; var; var = var->next)
104            if (var->name == name)
105                return var;
106    for (loop = frame->loops; loop; loop = loop->next)
107        if (loop->var.name == name)
108            return &loop->var;
109    return NULL;
110}
111
112
113static void set_frame(struct frame *frame)
114{
115    curr_frame = frame;
116    next_table = &frame->tables;
117    next_loop = &frame->loops;
118    next_vec = &frame->vecs;
119    next_obj = &frame->objs;
120    last_vec = NULL;
121}
122
123
124static void make_var(const char *id, struct expr *expr)
125{
126    struct table *table;
127
128    table = zalloc_type(struct table);
129    table->vars = zalloc_type(struct var);
130    table->vars->name = id;
131    table->vars->frame = curr_frame;
132    table->vars->table = table;
133    table->rows = zalloc_type(struct row);
134    table->rows->table = table;
135    table->rows->values = zalloc_type(struct value);
136    table->rows->values->expr = expr;
137    table->rows->values->row = table->rows;
138    table->active_row = table->rows;
139    *next_table = table;
140    next_table = &table->next;
141}
142
143
144static void make_loop(const char *id, struct expr *from, struct expr *to)
145{
146    struct loop *loop;
147
148    loop = alloc_type(struct loop);
149    loop->var.name = id;
150    loop->var.next = NULL;
151    loop->var.frame = curr_frame;
152    loop->var.table = NULL;
153    loop->from.expr = from;
154    loop->from.row = NULL;
155    loop->from.next = NULL;
156    loop->to.expr = to;
157    loop->to.row = NULL;
158    loop->to.next = NULL;
159    loop->next = NULL;
160    loop->active = 0;
161    loop->initialized = 0;
162    *next_loop = loop;
163    next_loop = &loop->next;
164}
165
166
167static struct obj *new_obj(enum obj_type type)
168{
169    struct obj *obj;
170
171    obj = alloc_type(struct obj);
172    obj->type = type;
173    obj->name = NULL;
174    obj->frame = curr_frame;
175    obj->next = NULL;
176    obj->lineno = lineno;
177    return obj;
178}
179
180
181static int dbg_delete(const char *name)
182{
183    struct vec *vec;
184    struct obj *obj;
185
186    vec = find_vec(curr_frame, name);
187    if (vec) {
188        delete_vec(vec);
189        return 1;
190    }
191    obj = find_obj(curr_frame, name);
192    if (obj) {
193        delete_obj(obj);
194        return 1;
195    }
196    yyerrorf("unknown item \"%s\"", name);
197    return 0;
198}
199
200
201static int dbg_move(const char *name, int anchor, const char *dest)
202{
203    struct vec *to, *vec;
204    struct obj *obj;
205    struct vec **anchors[3];
206    int n_anchors;
207
208    to = find_vec(curr_frame, dest);
209    if (!to) {
210        yyerrorf("unknown vector \"%s\"", dest);
211        return 0;
212    }
213    vec = find_vec(curr_frame, name);
214    if (vec) {
215        if (anchor) {
216            yyerrorf("invalid anchor (%d > 0)", anchor);
217            return 0;
218        }
219        vec->base = to;
220        return 1;
221    }
222    obj = find_obj(curr_frame, name);
223    if (!obj) {
224        yyerrorf("unknown item \"%s\"", name);
225        return 0;
226    }
227    n_anchors = obj_anchors(obj, anchors);
228    if (anchor >= n_anchors) {
229        yyerrorf("invalid anchor (%d > %d)", anchor, n_anchors-1);
230        return 0;
231    }
232    *anchors[anchor] = to;
233    return 1;
234}
235
236
237static int dbg_print(const struct expr *expr)
238{
239    const char *s;
240    struct num num;
241
242    s = eval_str(expr, curr_frame);
243    if (s) {
244        printf("%s\n", s);
245        return 1;
246    }
247    num = eval_num(expr, curr_frame);
248    if (is_undef(num))
249        return 0;
250    printf("%lg%s\n", num.n, str_unit(num));
251    return 1;
252}
253
254
255static void append_root_frame(void)
256{
257    root_frame->prev = last_frame;
258    if (last_frame)
259        last_frame->next = root_frame;
260    else
261        frames = root_frame;
262}
263
264
265%}
266
267
268%union {
269    struct num num;
270    char *str;
271    const char *id;
272    struct expr *expr;
273    struct frame *frame;
274    struct table *table;
275    struct var *var;
276    struct row *row;
277    struct value *value;
278    struct vec *vec;
279    struct obj *obj;
280    enum pad_type pt;
281    enum meas_type mt;
282    struct {
283        int inverted;
284        int max;
285    } mo;
286};
287
288
289%token START_FPD START_EXPR START_VAR START_VALUES
290%token TOK_SET TOK_LOOP TOK_PACKAGE TOK_FRAME TOK_TABLE TOK_VEC
291%token TOK_PAD TOK_RPAD TOK_HOLE TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
292%token TOK_MEAS TOK_MEASX TOK_MEASY TOK_UNIT
293%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
294%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_PRINT TOK_DBG_DUMP
295%token TOK_DBG_EXIT TOK_DBG_TSORT
296
297%token <num> NUMBER
298%token <str> STRING
299%token <id> ID LABEL
300
301%type <table> table
302%type <var> vars var
303%type <row> rows
304%type <value> row value opt_value_list
305%type <vec> vec base qbase
306%type <obj> object obj meas
307%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
308%type <num> opt_num
309%type <str> opt_string
310%type <pt> pad_type
311%type <mt> meas_type
312%type <mo> meas_op
313
314%%
315
316all:
317    START_FPD
318        {
319            root_frame = zalloc_type(struct frame);
320            set_frame(root_frame);
321            id_sin = unique("sin");
322            id_cos = unique("cos");
323            id_sqrt = unique("sqrt");
324        }
325        fpd
326        {
327            append_root_frame();
328        }
329    | START_EXPR expr
330        {
331            expr_result = $2;
332        }
333    | START_VAR ID opt_value_list
334        {
335            var_id = $2;
336            var_value_list = $3;
337        }
338    | START_VALUES row
339        {
340            var_value_list = $2;
341        }
342    ;
343
344fpd:
345    | frame_defs part_name opt_unit frame_items
346    ;
347
348part_name:
349    TOK_PACKAGE STRING
350        {
351            const char *p;
352
353            if (!*$2) {
354                yyerrorf("invalid package name");
355                YYABORT;
356            }
357            for (p = $2; *p; *p++)
358                if (*p < 32 || *p > 126) {
359                    yyerrorf("invalid package name");
360                    YYABORT;
361                }
362            pkg_name = $2;
363        }
364    ;
365
366opt_unit:
367    | TOK_UNIT ID
368        {
369            if (!strcmp($2, "mm"))
370                curr_unit = curr_unit_mm;
371            else if (!strcmp($2, "mil"))
372                curr_unit = curr_unit_mil;
373            else if (!strcmp($2, "auto"))
374                curr_unit = curr_unit_auto;
375            else {
376                yyerrorf("unrecognized unit \"%s\"", $2);
377                YYABORT;
378            }
379        }
380    ;
381
382frame_defs:
383    | frame_defs frame_def
384    ;
385
386frame_def:
387    TOK_FRAME ID '{'
388        {
389            if (find_frame($2)) {
390                yyerrorf("duplicate frame \"%s\"", $2);
391                YYABORT;
392            }
393            curr_frame = zalloc_type(struct frame);
394            curr_frame->name = $2;
395            set_frame(curr_frame);
396            curr_frame->prev = last_frame;
397            if (last_frame)
398                last_frame->next = curr_frame;
399            else
400                frames = curr_frame;
401            last_frame = curr_frame;
402        }
403        frame_items '}'
404        {
405            set_frame(root_frame);
406        }
407    ;
408
409frame_items:
410    | measurements
411    | frame_item frame_items
412    ;
413
414frame_item:
415    table
416    | TOK_SET ID '=' expr
417        {
418            if (find_var(curr_frame, $2)) {
419                yyerrorf("duplicate variable \"%s\"", $2);
420                YYABORT;
421            }
422            make_var($2, $4);
423        }
424    | TOK_LOOP ID '=' expr ',' expr
425        {
426            if (find_var(curr_frame, $2)) {
427                yyerrorf("duplicate variable \"%s\"", $2);
428                YYABORT;
429            }
430            make_loop($2, $4, $6);
431        }
432    | vec
433    | LABEL vec
434        {
435            if (find_label(curr_frame, $1)) {
436                yyerrorf("duplicate label \"%s\"", $1);
437                YYABORT;
438            }
439            $2->name = $1;
440        }
441    | object
442    | LABEL object
443        {
444            if (find_label(curr_frame, $1)) {
445                yyerrorf("duplicate label \"%s\"", $1);
446                YYABORT;
447            }
448            $2->name = $1;
449        }
450    | TOK_DBG_DEL ID
451        {
452            if (!dbg_delete($2))
453                YYABORT;
454        }
455    | TOK_DBG_MOVE ID opt_num ID
456        {
457            if (!dbg_move($2, $3.n, $4))
458                YYABORT;
459        }
460    | TOK_DBG_PRINT expr
461        {
462            if (!dbg_print($2))
463                YYABORT;
464        }
465    | debug_item
466    ;
467
468debug_item:
469    TOK_DBG_DUMP
470        {
471            /*
472             * It's okay to do append the root frame multiple
473             * times. If more frames are added afterwards, they
474             * just replace the root frame until it gets appended a
475             * final time when parsing ends.
476             */
477            append_root_frame();
478            if (!dump(stdout)) {
479                perror("stdout");
480                exit(1);
481            }
482        }
483    | TOK_DBG_EXIT
484        {
485            exit(0);
486        }
487    | TOK_DBG_TSORT '{'
488        {
489            tsort = begin_tsort();
490        }
491        sort_items '}'
492        {
493            void **sort, **walk;
494
495            sort = end_tsort(tsort);
496            for (walk = sort; *walk; walk++)
497                printf("%s\n", (char *) *walk);
498            free(sort);
499        }
500    ;
501
502sort_items:
503    | sort_items '+' ID
504        {
505            add_node(tsort, (void *) $3, 0);
506        }
507    | sort_items '-' ID
508        {
509            add_node(tsort, (void *) $3, 1);
510        }
511    | sort_items ID ID opt_num
512        {
513            struct node *a, *b;
514
515            /* order is important here ! */
516            a = add_node(tsort, (void *) $2, 0);
517            b = add_node(tsort, (void *) $3, 0);
518            add_edge(a, b, $4.n);
519        }
520    ;
521
522table:
523    TOK_TABLE
524        {
525            $<table>$ = zalloc_type(struct table);
526            *next_table = $<table>$;
527            curr_table = $<table>$;
528            n_vars = 0;
529        }
530        '{' vars '}' rows
531        {
532            $$ = $<table>2;
533            $$->vars = $4;
534            $$->rows = $6;
535            $$->active_row = $6;
536            next_table = &$$->next;
537        }
538    ;
539
540vars:
541    var
542        {
543            $$ = $1;
544        }
545    | vars ',' var
546        {
547            struct var **walk;
548
549            $$ = $1;
550            for (walk = &$$; *walk; walk = &(*walk)->next);
551            *walk = $3;
552        }
553    ;
554
555var:
556    ID
557        {
558            if (find_var(curr_frame, $1)) {
559                yyerrorf("duplicate variable \"%s\"", $1);
560                YYABORT;
561            }
562            $$ = zalloc_type(struct var);
563            $$->name = $1;
564            $$->frame = curr_frame;
565            $$->table = curr_table;
566            $$->next = NULL;
567            n_vars++;
568        }
569    ;
570    
571    
572rows:
573        {
574            $$ = NULL;
575        }
576    | '{'
577        {
578            $<row>$ = alloc_type(struct row);
579            $<row>$->table = curr_table;
580            curr_row = $<row>$;;
581            n_values = 0;
582        }
583        row '}'
584        {
585            if (n_vars != n_values) {
586                yyerrorf("table has %d variables but row has "
587                    "%d values", n_vars, n_values);
588                YYABORT;
589            }
590            $<row>2->values = $3;
591        }
592        rows
593        {
594            $$ = $<row>2;
595            $$->next = $6;
596        }
597    ;
598
599row:
600    value
601        {
602            $$ = $1;
603        }
604    | row ',' value
605        {
606            struct value **walk;
607
608            $$ = $1;
609            for (walk = &$$; *walk; walk = &(*walk)->next);
610            *walk = $3;
611        }
612    ;
613
614value:
615    expr
616        {
617            $$ = alloc_type(struct value);
618            $$->expr = $1;
619            $$->row = curr_row;
620            $$->next = NULL;
621            n_values++;
622        }
623    ;
624
625vec:
626    TOK_VEC base '(' expr ',' expr ')'
627        {
628            $$ = alloc_type(struct vec);
629            $$->name = NULL;
630            $$->base = $2;
631            $$->x = $4;
632            $$->y = $6;
633            $$->frame = curr_frame;
634            $$->next = NULL;
635            last_vec = $$;
636            *next_vec = $$;
637            next_vec = &$$->next;
638        }
639    ;
640
641base:
642    '@'
643        {
644            $$ = NULL;
645        }
646    | '.'
647        {
648            $$ = last_vec;
649            if (!$$) {
650                yyerrorf(". without predecessor");
651                YYABORT;
652            }
653        }
654    | ID
655        {
656            $$ = find_vec(curr_frame, $1);
657            if (!$$) {
658                yyerrorf("unknown vector \"%s\"", $1);
659                YYABORT;
660            }
661        }
662    ;
663
664object:
665    obj
666        {
667            $$ = $1;
668            *next_obj = $1;
669            next_obj = &$1->next;
670        }
671    ;
672
673obj:
674    TOK_PAD STRING base base pad_type
675        {
676            $$ = new_obj(ot_pad);
677            $$->base = $3;
678            $$->u.pad.name = $2;
679            $$->u.pad.other = $4;
680            $$->u.pad.rounded = 0;
681            $$->u.pad.type = $5;
682        }
683    | TOK_RPAD STRING base base pad_type
684        {
685            $$ = new_obj(ot_pad);
686            $$->base = $3;
687            $$->u.pad.name = $2;
688            $$->u.pad.other = $4;
689            $$->u.pad.rounded = 1;
690            $$->u.pad.type = $5;
691        }
692    | TOK_HOLE base base
693        {
694            $$ = new_obj(ot_hole);
695            $$->base = $2;
696            $$->u.hole.other = $3;
697        }
698    | TOK_RECT base base opt_expr
699        {
700            $$ = new_obj(ot_rect);
701            $$->base = $2;
702            $$->u.rect.other = $3;
703            $$->u.rect.width = $4;
704        }
705    | TOK_LINE base base opt_expr
706        {
707            $$ = new_obj(ot_line);
708            $$->base = $2;
709            $$->u.line.other = $3;
710            $$->u.line.width = $4;
711        }
712    | TOK_CIRC base base opt_expr
713        {
714            $$ = new_obj(ot_arc);
715            $$->base = $2;
716            $$->u.arc.start = $3;
717            $$->u.arc.end = $3;
718            $$->u.arc.width = $4;
719        }
720    | TOK_ARC base base base opt_expr
721        {
722            $$ = new_obj(ot_arc);
723            $$->base = $2;
724            $$->u.arc.start = $3;
725            $$->u.arc.end = $4;
726            $$->u.arc.width = $5;
727        }
728    | TOK_FRAME ID
729        {
730            $<num>$.n = lineno;
731        }
732            base
733        {
734            $$ = new_obj(ot_frame);
735            $$->base = $4;
736            $$->u.frame.ref = find_frame($2);
737            if (!$$->u.frame.ref) {
738                yyerrorf("unknown frame \"%s\"", $2);
739                YYABORT;
740            }
741            if (!$$->u.frame.ref->active_ref)
742                $$->u.frame.ref->active_ref = $$;
743            $$->u.frame.lineno = $<num>3.n;
744        }
745    ;
746
747pad_type:
748        {
749            $$ = pt_normal;
750        }
751    | ID
752        {
753            if (!strcmp($1, "bare"))
754                $$ = pt_bare;
755            else if (!strcmp($1, "paste"))
756                $$ = pt_paste;
757            else if (!strcmp($1, "mask"))
758                $$ = pt_mask;
759            else {
760                yyerrorf("unknown pad type \"%s\"", $1);
761                YYABORT;
762            }
763        }
764    ;
765
766measurements:
767    meas
768        {
769            *next_obj = $1;
770            next_obj = &$1->next;
771        }
772    | measurements meas
773        {
774            *next_obj = $2;
775            next_obj = &$2->next;
776        }
777    | measurements debug_item
778    ;
779
780meas:
781    meas_type opt_string qbase meas_op qbase opt_expr
782        {
783            struct meas *meas;
784
785            $$ = new_obj(ot_meas);
786            meas = &$$->u.meas;
787            meas->type = $4.max ? $1+3 : $1;
788            meas->label = $2;
789            $$->base = $3;
790            meas->inverted = $4.inverted;
791            meas->high = $5;
792            meas->offset = $6;
793            $$->next = NULL;
794        }
795    ;
796
797qbase:
798    ID
799        {
800            $$ = find_vec(root_frame, $1);
801            if (!$$) {
802                yyerrorf("unknown vector \"%s\"", $1);
803                YYABORT;
804            }
805        }
806    | ID '.' ID
807        {
808            const struct frame *frame;
809
810            frame = find_frame($1);
811            $$ = frame ? find_vec(frame, $3) : NULL;
812            if (!$$) {
813                yyerrorf("unknown vector \"%s.%s\"", $1, $3);
814                YYABORT;
815            }
816        }
817    ;
818
819meas_type:
820    TOK_MEAS
821        {
822            $$ = mt_xy_next;
823        }
824    | TOK_MEASX
825        {
826            $$ = mt_x_next;
827        }
828    | TOK_MEASY
829        {
830            $$ = mt_y_next;
831        }
832    ;
833
834meas_op:
835    TOK_NEXT
836        {
837            $$.max = 0;
838            $$.inverted = 0;
839        }
840    | TOK_NEXT_INVERTED
841        {
842            $$.max = 0;
843            $$.inverted = 1;
844        }
845    | TOK_MAX
846        {
847            $$.max = 1;
848            $$.inverted = 0;
849        }
850    | TOK_MAX_INVERTED
851        {
852            $$.max = 1;
853            $$.inverted = 1;
854        }
855    ;
856
857opt_num:
858        {
859            $$.n = 0;
860        }
861    | NUMBER
862        {
863            $$ = $1;
864        }
865    ;
866
867opt_string:
868        {
869            $$ = NULL;
870        }
871    | STRING
872        {
873            $$ = $1;
874        }
875    ;
876
877opt_expr:
878        {
879            $$ = NULL;
880        }
881    | expr
882        {
883            $$ = $1;
884        }
885    ;
886
887expr:
888    add_expr
889        {
890            $$ = $1;
891        }
892    ;
893
894add_expr:
895    mult_expr
896        {
897            $$ = $1;
898        }
899    | add_expr '+' mult_expr
900        {
901            $$ = binary_op(op_add, $1, $3);
902        }
903    | add_expr '-' mult_expr
904        {
905            $$ = binary_op(op_sub, $1, $3);
906        }
907    ;
908
909mult_expr:
910    unary_expr
911        {
912            $$ = $1;
913        }
914    | mult_expr '*' unary_expr
915        {
916            $$ = binary_op(op_mult, $1, $3);
917        }
918    | mult_expr '/' unary_expr
919        {
920            $$ = binary_op(op_div, $1, $3);
921        }
922    ;
923
924unary_expr:
925    primary_expr
926        {
927            $$ = $1;
928        }
929    | '-' primary_expr
930        {
931            $$ = binary_op(op_minus, $2, NULL);
932        }
933    ;
934
935primary_expr:
936    NUMBER
937        {
938            $$ = new_op(op_num);
939            $$->u.num = $1;
940        }
941    | ID
942        {
943            $$ = new_op(op_var);
944            $$->u.var = $1;
945        }
946    | STRING
947        {
948            $$ = new_op(op_string);
949            $$->u.str = $1;
950        }
951    | '(' expr ')'
952        {
953            $$ = $2;
954        }
955    | ID '(' expr ')'
956        {
957            if ($1 == id_sin)
958                $$ = binary_op(op_sin, $3, NULL);
959            else if ($1 == id_cos)
960                $$ = binary_op(op_cos, $3, NULL);
961            else if ($1 == id_sqrt)
962                $$ = binary_op(op_sqrt, $3, NULL);
963            else {
964                yyerrorf("unknown function \"%s\"", $1);
965                YYABORT;
966            }
967        }
968    ;
969
970/* special sub-grammar */
971
972opt_value_list:
973        {
974            $$ = NULL;
975        }
976    | '=' row
977        {
978            $$ = $2;
979        }
980    ;
981

Archive Download this file

Branches:
master



interactive