Root/fpd.y

Source at commit 7081258910b767841129be93bff3c971d8db6cf1 created 7 years 2 months ago.
By Erich Heinzle, diff for gEDA PCB export in fped
1%{
2/*
3 * fpd.y - FootPrint Definition language
4 *
5 * Written 2009-2012 by Werner Almesberger
6 * Copyright 2009-2012 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 "coord.h"
21#include "expr.h"
22#include "obj.h"
23#include "meas.h"
24#include "gui_status.h"
25#include "gui_inst.h" /* for %meas */
26#include "dump.h"
27#include "tsort.h"
28#include "fpd.h"
29
30#include "y.tab.h"
31
32
33struct expr *expr_result;
34const char *var_id;
35struct value *var_value_list;
36
37
38static struct frame *curr_frame;
39static struct table *curr_table;
40static struct row *curr_row;
41
42static struct vec *last_vec = NULL;
43
44static struct table **next_table;
45static struct loop **next_loop;
46static struct vec **next_vec;
47static struct obj **next_obj;
48
49static int n_vars, n_values;
50
51static const char *id_sin, *id_cos, *id_sqrt, *id_floor;
52
53static struct tsort *tsort;
54
55
56/* ----- lookup functions -------------------------------------------------- */
57
58
59static struct frame *find_frame(const char *name)
60{
61    struct frame *f;
62
63    for (f = frames->next; f; f = f->next)
64        if (f->name == name)
65            return f;
66    return NULL;
67}
68
69
70static struct vec *find_vec(const struct frame *frame, const char *name)
71{
72    struct vec *v;
73
74    for (v = frame->vecs; v; v = v->next)
75        if (v->name == name)
76            return v;
77    return NULL;
78}
79
80
81static struct obj *find_obj(const struct frame *frame, const char *name)
82{
83    struct obj *obj;
84
85    for (obj = frame->objs; obj; obj = obj->next)
86        if (obj->name == name)
87            return obj;
88    return NULL;
89}
90
91
92static int find_label(const struct frame *frame, const char *name)
93{
94    if (find_vec(frame, name))
95        return 1;
96    if (find_obj(frame, name))
97        return 1;
98    return 0;
99}
100
101
102static struct var *find_var(const struct frame *frame, const char *name)
103{
104    const struct table *table;
105    struct var *var;
106    struct loop *loop;
107
108    for (table = frame->tables; table; table = table->next)
109        for (var = table->vars; var; var = var->next)
110            if (!var->key && var->name == name)
111                return var;
112    for (loop = frame->loops; loop; loop = loop->next)
113        if (loop->var.name == name)
114            return &loop->var;
115    return NULL;
116}
117
118
119/* ----- item creation ----------------------------------------------------- */
120
121
122static void set_frame(struct frame *frame)
123{
124    curr_frame = frame;
125    next_table = &frame->tables;
126    next_loop = &frame->loops;
127    next_vec = &frame->vecs;
128    next_obj = &frame->objs;
129    last_vec = NULL;
130}
131
132
133static void make_var(const char *id, int key, struct expr *expr)
134{
135    struct table *table;
136
137    table = zalloc_type(struct table);
138    table->vars = zalloc_type(struct var);
139    table->vars->name = id;
140    table->vars->frame = curr_frame;
141    table->vars->table = table;
142    table->vars->key = key;
143    table->rows = zalloc_type(struct row);
144    table->rows->table = table;
145    table->rows->values = zalloc_type(struct value);
146    table->rows->values->expr = expr;
147    table->rows->values->row = table->rows;
148    table->active_row = table->rows;
149    *next_table = table;
150    next_table = &table->next;
151}
152
153
154static void make_loop(const char *id, struct expr *from, struct expr *to)
155{
156    struct loop *loop;
157
158    loop = alloc_type(struct loop);
159    loop->var.name = id;
160    loop->var.next = NULL;
161    loop->var.frame = curr_frame;
162    loop->var.table = NULL;
163    loop->from.expr = from;
164    loop->from.row = NULL;
165    loop->from.next = NULL;
166    loop->to.expr = to;
167    loop->to.row = NULL;
168    loop->to.next = NULL;
169    loop->next = NULL;
170    loop->active = 0;
171    loop->initialized = 0;
172    *next_loop = loop;
173    next_loop = &loop->next;
174}
175
176
177static struct obj *new_obj(enum obj_type type)
178{
179    struct obj *obj;
180
181    obj = alloc_type(struct obj);
182    obj->type = type;
183    obj->name = NULL;
184    obj->frame = curr_frame;
185    obj->next = NULL;
186    obj->lineno = lineno;
187    return obj;
188}
189
190
191/* ---- frame qualifiers --------------------------------------------------- */
192
193
194static int duplicate_qualifier(const struct frame_qual *a,
195    const struct frame_qual *b)
196{
197    if (!b)
198        return 0;
199    if (a != b && a->frame == b->frame) {
200        yyerrorf("duplicate qualifier \"%s\"", a->frame->name);
201        return 1;
202    }
203    if (b && duplicate_qualifier(a, b->next))
204        return 1;
205    return duplicate_qualifier(a->next, a->next);
206}
207
208
209static int can_reach(const struct frame *curr, const struct frame_qual *qual,
210    const struct frame *end)
211{
212    const struct obj *obj;
213
214    if (curr == end)
215        return !qual;
216
217    /*
218     * Don't recurse for removing the qualifier alone. We require a frame
219     * reference step as well, so that things like foo.foo.foo.bar.vec
220     * aren't allowed.
221     *
222     * Since a duplicate qualifier can never work, we test for this error
223     * explicitly in "duplicate_qualifier".
224     */
225    if (qual && curr == qual->frame)
226        qual = qual->next;
227
228    for (obj = curr->objs; obj; obj = obj->next)
229        if (obj->type == ot_frame)
230            if (can_reach(obj->u.frame.ref, qual, end))
231                return 1;
232    return 0;
233}
234
235
236static int check_qbase(struct qbase *qbase)
237{
238    if (duplicate_qualifier(qbase->qualifiers, qbase->qualifiers))
239        return 0;
240
241    if (!can_reach(frames, qbase->qualifiers, qbase->vec->frame))
242        yywarn("not all qualifiers can be reached");
243    return 1;
244}
245
246
247/* ----- debugging directives ---------------------------------------------- */
248
249
250static int dbg_delete(const char *frame_name, const char *name)
251{
252    struct vec *vec;
253    struct obj *obj;
254    struct frame *frame;
255
256    if (!frame_name) {
257        frame = curr_frame;
258    } else {
259        frame = find_frame(frame_name);
260        if (!frame) {
261            yyerrorf("unknown frame \"%s\"", frame_name);
262            return 0;
263        }
264    }
265    vec = find_vec(frame, name);
266    if (vec) {
267        delete_vec(vec);
268        return 1;
269    }
270    obj = find_obj(frame, name);
271    if (obj) {
272        delete_obj(obj);
273        return 1;
274    }
275    if (!frame_name) {
276        frame = find_frame(name);
277        if (frame) {
278            if (curr_frame == frame) {
279                yyerrorf("a frame can't delete itself");
280                return 0;
281            }
282            delete_frame(frame);
283            return 1;
284        }
285    }
286    if (frame_name)
287        yyerrorf("unknown item \"%s.%s\"", frame_name, name);
288    else
289        yyerrorf("unknown item \"%s\"", name);
290    return 0;
291}
292
293
294static int dbg_move(const char *name, int anchor, const char *dest)
295{
296    struct vec *to, *vec;
297    struct obj *obj;
298    struct vec **anchors[3];
299    int n_anchors;
300
301    to = find_vec(curr_frame, dest);
302    if (!to) {
303        yyerrorf("unknown vector \"%s\"", dest);
304        return 0;
305    }
306    vec = find_vec(curr_frame, name);
307    if (vec) {
308        if (anchor) {
309            yyerrorf("invalid anchor (%d > 0)", anchor);
310            return 0;
311        }
312        vec->base = to;
313        return 1;
314    }
315    obj = find_obj(curr_frame, name);
316    if (!obj) {
317        yyerrorf("unknown item \"%s\"", name);
318        return 0;
319    }
320    n_anchors = obj_anchors(obj, anchors);
321    if (anchor >= n_anchors) {
322        yyerrorf("invalid anchor (%d > %d)", anchor, n_anchors-1);
323        return 0;
324    }
325    *anchors[anchor] = to;
326    return 1;
327}
328
329
330/*
331 * @@@ This is very similar to what we do in rule "obj". Consider merging.
332 */
333
334/*
335 * We need to pass base_frame and base_vec, not just the vector (with the
336 * frame implied) since we can also reference the frame's origin, whose
337 * "vector" is NULL.
338 */
339
340static int dbg_link_frame(const char *frame_name,
341    struct frame *base_frame, struct vec *base_vec)
342{
343    struct frame *frame;
344    struct obj *obj;
345
346    assert(!base_vec || base_vec->frame == base_frame);
347    frame = find_frame(frame_name);
348    if (!frame) {
349        yyerrorf("unknown frame \"%s\"", frame_name);
350        return 0;
351    }
352    /* this can only fail in %frame */
353    if (is_parent_of(frame, base_frame)) {
354        yyerrorf("frame \"%s\" is a parent of \"%s\"",
355            frame->name, base_frame->name);
356        return 0;
357    }
358    obj = new_obj(ot_frame);
359    obj->base = base_vec;
360    obj->frame = base_frame;
361    obj->u.frame.ref = frame;
362    connect_obj(base_frame, obj);
363    if (!frame->active_ref)
364        frame->active_ref = obj;
365    return 1;
366}
367
368
369int dbg_print(const struct expr *expr, const struct frame *frame)
370{
371    const char *s;
372    struct num num;
373
374    s = eval_str(expr, frame);
375    if (s) {
376        printf("%s\n", s);
377        return 1;
378    }
379    num = eval_num(expr, frame);
380    if (is_undef(num))
381        return 0;
382    printf("%lg%s\n", num.n, str_unit(num));
383    return 1;
384}
385
386
387static int dbg_meas(const char *name)
388{
389    const struct obj *obj;
390    const struct inst *inst;
391    struct coord a1, b1;
392    char *s;
393
394    obj = find_obj(frames, name);
395    if (!obj) {
396        yyerrorf("unknown object \"%s\"", name);
397        return 0;
398    }
399
400    /* from fped.c:main */
401
402    if (!pkg_name)
403                pkg_name = stralloc("_");
404        reporter = report_to_stderr;
405    if (!instantiate())
406        return 0;
407
408    inst = find_meas_hint(obj);
409    if (!inst) {
410        yyerrorf("measurement \"%s\" was not instantiated", name);
411        return 0;
412    }
413
414    project_meas(inst, &a1, &b1);
415    s = format_len(obj->u.meas.label ? obj->u.meas.label : "",
416        dist_point(a1, b1), curr_unit);
417    printf("%s\n", s);
418    free(s);
419
420    return 1;
421}
422
423
424%}
425
426
427%union {
428    struct num num;
429    int flag;
430    char *str;
431    const char *id;
432    struct expr *expr;
433    struct frame *frame;
434    struct table *table;
435    struct var *var;
436    struct row *row;
437    struct value *value;
438    struct vec *vec;
439    struct obj *obj;
440    enum pad_type pt;
441    enum meas_type mt;
442    struct {
443        int inverted;
444        int max;
445    } mo;
446    struct {
447        struct frame *frame;
448        struct vec *vec;
449    } qvec;
450    struct qbase {
451        struct vec *vec;
452        struct frame_qual *qualifiers;
453    } qbase;
454};
455
456
457%token START_FPD START_EXPR START_VAR START_VALUES
458%token TOK_SET TOK_LOOP TOK_PACKAGE TOK_FRAME TOK_TABLE TOK_VEC
459%token TOK_PAD TOK_RPAD TOK_HOLE TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
460%token TOK_MEAS TOK_MEASX TOK_MEASY TOK_UNIT
461%token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
462%token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME
463%token TOK_DBG_PRINT TOK_DBG_IPRINT
464%token TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT TOK_DBG_MEAS
465%token TOK_ALLOW_HOLES TOK_ALLOW_OVERLAP TOK_ALLOW_TOUCH
466
467%token <num> NUMBER
468%token <str> STRING
469%token <id> ID LABEL
470
471%type <table> table
472%type <var> vars var
473%type <row> rows
474%type <value> row value opt_value_list
475%type <vec> vec base
476%type <obj> object obj meas unlabeled_meas
477%type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
478%type <num> opt_num
479%type <flag> opt_key
480%type <frame> frame_qualifier
481%type <str> opt_string
482%type <pt> pad_type
483%type <mt> meas_type
484%type <mo> meas_op
485%type <qvec> qualified_base
486%type <qbase> qbase qbase_unchecked
487
488%%
489
490all:
491    START_FPD
492        {
493            frames = zalloc_type(struct frame);
494            set_frame(frames);
495            id_sin = unique("sin");
496            id_cos = unique("cos");
497            id_sqrt = unique("sqrt");
498            id_floor = unique("floor");
499        }
500        fpd
501    | START_EXPR expr
502        {
503            expr_result = $2;
504        }
505    | START_VAR ID opt_value_list
506        {
507            var_id = $2;
508            var_value_list = $3;
509        }
510    | START_VALUES row
511        {
512            var_value_list = $2;
513        }
514    ;
515
516fpd:
517    frame_defs part_name opt_setup opt_frame_items opt_measurements
518    | frame_defs setup opt_frame_items opt_measurements
519    | frame_defs frame_items opt_measurements
520    | frame_defs opt_measurements
521    ;
522
523part_name:
524    TOK_PACKAGE STRING
525        {
526            const char *p;
527
528            if (!*$2) {
529                yyerrorf("invalid package name");
530                YYABORT;
531            }
532            for (p = $2; *p; *p++)
533                if (*p < 32 || *p > 126) {
534                    yyerrorf("invalid package name");
535                    YYABORT;
536                }
537            pkg_name = $2;
538        }
539    ;
540
541opt_setup:
542    | setup
543    ;
544
545setup:
546    unit
547    | allow_pads
548    | allow_holes
549    | unit allow_pads
550    | unit allow_pads allow_holes
551    | unit allow_holes
552    | unit allow_holes allow_pads
553    | allow_pads unit
554    | allow_pads unit allow_holes
555    | allow_holes unit
556    | allow_holes unit allow_pads
557    ;
558
559unit:
560    TOK_UNIT ID
561        {
562            if (!strcmp($2, "mm"))
563                curr_unit = curr_unit_mm;
564            else if (!strcmp($2, "mil"))
565                curr_unit = curr_unit_mil;
566            else if (!strcmp($2, "auto"))
567                curr_unit = curr_unit_auto;
568            else {
569                yyerrorf("unrecognized unit \"%s\"", $2);
570                YYABORT;
571            }
572        }
573    ;
574
575allow_pads:
576    TOK_ALLOW_TOUCH
577        {
578            allow_overlap = ao_touch;
579        }
580    | TOK_ALLOW_OVERLAP
581        {
582            allow_overlap = ao_any;
583        }
584    ;
585
586allow_holes:
587    TOK_ALLOW_HOLES
588        {
589            holes_linked = 0;
590        }
591    ;
592
593frame_defs:
594    | frame_defs frame_def
595    ;
596
597frame_def:
598    TOK_FRAME ID '{'
599        {
600            if (find_frame($2)) {
601                yyerrorf("duplicate frame \"%s\"", $2);
602                YYABORT;
603            }
604            curr_frame = zalloc_type(struct frame);
605            curr_frame->name = $2;
606            set_frame(curr_frame);
607            curr_frame->next = frames->next;
608            frames->next = curr_frame;
609        }
610        opt_frame_items '}'
611        {
612            set_frame(frames);
613        }
614    ;
615
616opt_frame_items:
617    | frame_items
618    ;
619
620frame_items:
621    frame_item
622    | frame_item frame_items
623    ;
624
625frame_item:
626    table
627    | TOK_SET opt_key ID '=' expr
628        {
629            if (!$2 && find_var(curr_frame, $3)) {
630                yyerrorf("duplicate variable \"%s\"", $3);
631                YYABORT;
632            }
633            make_var($3, $2, $5);
634        }
635    | TOK_LOOP ID '=' expr ',' expr
636        {
637            if (find_var(curr_frame, $2)) {
638                yyerrorf("duplicate variable \"%s\"", $2);
639                YYABORT;
640            }
641            make_loop($2, $4, $6);
642        }
643    | vec
644    | LABEL vec
645        {
646            if (find_label(curr_frame, $1)) {
647                yyerrorf("duplicate label \"%s\"", $1);
648                YYABORT;
649            }
650            $2->name = $1;
651        }
652    | object
653    | LABEL object
654        {
655            if (find_label(curr_frame, $1)) {
656                yyerrorf("duplicate label \"%s\"", $1);
657                YYABORT;
658            }
659            $2->name = $1;
660        }
661    | debug_item
662    ;
663
664debug_item:
665    TOK_DBG_DEL ID
666        {
667            if (!dbg_delete(NULL, $2))
668                YYABORT;
669        }
670    | TOK_DBG_DEL ID '.' ID
671        {
672            if (!dbg_delete($2, $4))
673                YYABORT;
674        }
675    | TOK_DBG_MOVE ID opt_num ID
676        {
677            if (!dbg_move($2, $3.n, $4))
678                YYABORT;
679        }
680    | TOK_DBG_FRAME ID qualified_base
681        {
682            if (!dbg_link_frame($2, $3.frame, $3.vec))
683                YYABORT;
684        }
685    | TOK_DBG_PRINT expr
686        {
687            if (!dbg_print($2, curr_frame))
688                YYABORT;
689        }
690    | TOK_DBG_MEAS ID
691        {
692            if (!dbg_meas($2))
693                YYABORT;
694        }
695    | TOK_DBG_DUMP
696        {
697            if (!dump(stdout, NULL)) {
698                perror("stdout");
699                exit(1);
700            }
701        }
702    | TOK_DBG_EXIT
703        {
704            exit(0);
705        }
706    | TOK_DBG_TSORT '{'
707        {
708            tsort = begin_tsort();
709        }
710        sort_items '}'
711        {
712            void **sort, **walk;
713
714            sort = end_tsort(tsort);
715            for (walk = sort; *walk; walk++)
716                printf("%s\n", (char *) *walk);
717            free(sort);
718        }
719    ;
720
721sort_items:
722    | sort_items '+' ID
723        {
724            add_node(tsort, (void *) $3, 0);
725        }
726    | sort_items '-' ID
727        {
728            add_node(tsort, (void *) $3, 1);
729        }
730    | sort_items ID ID opt_num
731        {
732            struct node *a, *b;
733
734            /* order is important here ! */
735            a = add_node(tsort, (void *) $2, 0);
736            b = add_node(tsort, (void *) $3, 0);
737            add_edge(a, b, $4.n);
738        }
739    ;
740
741table:
742    TOK_TABLE
743        {
744            $<table>$ = zalloc_type(struct table);
745            *next_table = $<table>$;
746            curr_table = $<table>$;
747            n_vars = 0;
748        }
749        '{' vars '}' rows
750        {
751            $$ = $<table>2;
752            $$->vars = $4;
753            $$->rows = $6;
754            $$->active_row = $6;
755            next_table = &$$->next;
756        }
757    ;
758
759vars:
760    var
761        {
762            $$ = $1;
763        }
764    | vars ',' var
765        {
766            struct var **walk;
767
768            $$ = $1;
769            for (walk = &$$; *walk; walk = &(*walk)->next);
770            *walk = $3;
771        }
772    ;
773
774var:
775    opt_key ID
776        {
777            if (!$1 && find_var(curr_frame, $2)) {
778                yyerrorf("duplicate variable \"%s\"", $2);
779                YYABORT;
780            }
781            $$ = zalloc_type(struct var);
782            $$->name = $2;
783            $$->frame = curr_frame;
784            $$->table = curr_table;
785            $$->key = $1;
786            $$->next = NULL;
787            n_vars++;
788        }
789    ;
790
791opt_key:
792        {
793            $$ = 0;
794        }
795    | '?'
796        {
797            $$ = 1;
798        }
799    ;
800
801rows:
802        {
803            $$ = NULL;
804        }
805    | '{'
806        {
807            $<row>$ = alloc_type(struct row);
808            $<row>$->table = curr_table;
809            curr_row = $<row>$;;
810            n_values = 0;
811        }
812        row '}'
813        {
814            if (n_vars != n_values) {
815                yyerrorf("table has %d variables but row has "
816                    "%d values", n_vars, n_values);
817                YYABORT;
818            }
819            $<row>2->values = $3;
820        }
821        rows
822        {
823            $$ = $<row>2;
824            $$->next = $6;
825        }
826    ;
827
828row:
829    value
830        {
831            $$ = $1;
832        }
833    | row ',' value
834        {
835            struct value **walk;
836
837            $$ = $1;
838            for (walk = &$$; *walk; walk = &(*walk)->next);
839            *walk = $3;
840        }
841    ;
842
843value:
844    expr
845        {
846            $$ = alloc_type(struct value);
847            $$->expr = $1;
848            $$->row = curr_row;
849            $$->next = NULL;
850            n_values++;
851        }
852    ;
853
854vec:
855    TOK_VEC base '(' expr ',' expr ')'
856        {
857            $$ = alloc_type(struct vec);
858            $$->nul_tag = 0;
859            $$->name = NULL;
860            $$->base = $2;
861            $$->x = $4;
862            $$->y = $6;
863            $$->frame = curr_frame;
864            $$->next = NULL;
865            last_vec = $$;
866            *next_vec = $$;
867            next_vec = &$$->next;
868        }
869    ;
870
871base:
872    '@'
873        {
874            $$ = NULL;
875        }
876    | '.'
877        {
878            $$ = last_vec;
879            if (!$$) {
880                yyerrorf(". without predecessor");
881                YYABORT;
882            }
883        }
884    | ID
885        {
886            $$ = find_vec(curr_frame, $1);
887            if (!$$)
888                $$ = (struct vec *) $1;
889        }
890    ;
891
892qualified_base:
893    base
894        {
895            $$.frame = curr_frame;
896            $$.vec = $1;
897        }
898    | frame_qualifier '@'
899        {
900            $$.frame = $1;
901            $$.vec = NULL;
902        }
903    | frame_qualifier ID
904        {
905            $$.frame = $1;
906            $$.vec = find_vec($1, $2);
907            if (!$$.vec) {
908                yyerrorf("unknown vector \"%s.%s\"",
909                    $1->name, $2);
910                YYABORT;
911            }
912        }
913    ;
914
915frame_qualifier:
916    ID '.'
917        {
918            $$ = find_frame($1);
919            if (!$$) {
920                yyerrorf("unknown frame \"%s\"", $1);
921                YYABORT;
922            }
923        }
924    ;
925
926object:
927    obj
928        {
929            $$ = $1;
930            *next_obj = $1;
931            next_obj = &$1->next;
932        }
933    ;
934
935obj:
936    TOK_PAD STRING base base pad_type
937        {
938            $$ = new_obj(ot_pad);
939            $$->base = $3;
940            $$->u.pad.name = $2;
941            $$->u.pad.other = $4;
942            $$->u.pad.rounded = 0;
943            $$->u.pad.type = $5;
944        }
945    | TOK_RPAD STRING base base pad_type
946        {
947            $$ = new_obj(ot_pad);
948            $$->base = $3;
949            $$->u.pad.name = $2;
950            $$->u.pad.other = $4;
951            $$->u.pad.rounded = 1;
952            $$->u.pad.type = $5;
953        }
954    | TOK_HOLE base base
955        {
956            $$ = new_obj(ot_hole);
957            $$->base = $2;
958            $$->u.hole.other = $3;
959        }
960    | TOK_RECT base base opt_expr
961        {
962            $$ = new_obj(ot_rect);
963            $$->base = $2;
964            $$->u.rect.other = $3;
965            $$->u.rect.width = $4;
966        }
967    | TOK_LINE base base opt_expr
968        {
969            $$ = new_obj(ot_line);
970            $$->base = $2;
971            $$->u.line.other = $3;
972            $$->u.line.width = $4;
973        }
974    | TOK_CIRC base base opt_expr
975        {
976            $$ = new_obj(ot_arc);
977            $$->base = $2;
978            $$->u.arc.start = $3;
979            $$->u.arc.end = $3;
980            $$->u.arc.width = $4;
981        }
982    | TOK_ARC base base base opt_expr
983        {
984            $$ = new_obj(ot_arc);
985            $$->base = $2;
986            $$->u.arc.start = $3;
987            $$->u.arc.end = $4;
988            $$->u.arc.width = $5;
989        }
990    | TOK_FRAME ID
991        {
992            $<num>$.n = lineno;
993        }
994            base
995        {
996            $$ = new_obj(ot_frame);
997            $$->base = $4;
998            $$->u.frame.ref = find_frame($2);
999            if (!$$->u.frame.ref) {
1000                yyerrorf("unknown frame \"%s\"", $2);
1001                YYABORT;
1002            }
1003            if (!$$->u.frame.ref->active_ref)
1004                $$->u.frame.ref->active_ref = $$;
1005            $$->u.frame.lineno = $<num>3.n;
1006        }
1007    | TOK_DBG_IPRINT expr
1008        {
1009            $$ = new_obj(ot_iprint);
1010            $$->base = NULL;
1011            $$->u.iprint.expr = $2;
1012        }
1013    ;
1014
1015pad_type:
1016        {
1017            $$ = pt_normal;
1018        }
1019    | ID
1020        {
1021            if (!strcmp($1, "bare"))
1022                $$ = pt_bare;
1023            else if (!strcmp($1, "trace"))
1024                $$ = pt_trace;
1025            else if (!strcmp($1, "paste"))
1026                $$ = pt_paste;
1027            else if (!strcmp($1, "mask"))
1028                $$ = pt_mask;
1029            else {
1030                yyerrorf("unknown pad type \"%s\"", $1);
1031                YYABORT;
1032            }
1033        }
1034    ;
1035
1036opt_measurements:
1037    | measurements
1038    ;
1039
1040measurements:
1041    unlabeled_meas /* @@@ hack */
1042        {
1043            *next_obj = $1;
1044            next_obj = &$1->next;
1045        }
1046    | measurements meas
1047        {
1048            *next_obj = $2;
1049            next_obj = &$2->next;
1050        }
1051    | measurements debug_item
1052    ;
1053
1054meas:
1055    unlabeled_meas
1056        {
1057            $$ = $1;
1058        }
1059    | LABEL unlabeled_meas
1060        {
1061            $$ = $2;
1062            if (find_label(curr_frame, $1)) {
1063                yyerrorf("duplicate label \"%s\"", $1);
1064                YYABORT;
1065            }
1066            $$->name = $1;
1067        }
1068    ;
1069
1070unlabeled_meas:
1071    meas_type opt_string qbase meas_op qbase opt_expr
1072        {
1073            struct meas *meas;
1074
1075            $$ = new_obj(ot_meas);
1076            meas = &$$->u.meas;
1077            meas->type = $4.max ? $1+3 : $1;
1078            meas->label = $2;
1079            $$->base = $3.vec;
1080            meas->low_qual = $3.qualifiers;
1081            meas->inverted = $4.inverted;
1082            meas->high = $5.vec;
1083            meas->high_qual = $5.qualifiers;
1084            meas->offset = $6;
1085            $$->next = NULL;
1086        }
1087    ;
1088
1089qbase:
1090    qbase_unchecked
1091        {
1092            $$ = $1;
1093            if (!check_qbase(&$$))
1094                YYABORT;
1095        }
1096    ;
1097
1098qbase_unchecked:
1099    ID
1100        {
1101            $$.vec = find_vec(frames, $1);
1102            if (!$$.vec) {
1103                yyerrorf("unknown vector \"%s\"", $1);
1104                YYABORT;
1105            }
1106            $$.qualifiers = NULL;
1107        }
1108    | ID '.' ID
1109        {
1110            const struct frame *frame;
1111
1112            frame = find_frame($1);
1113            $$.vec = frame ? find_vec(frame, $3) : NULL;
1114            if (!$$.vec) {
1115                yyerrorf("unknown vector \"%s.%s\"", $1, $3);
1116                YYABORT;
1117            }
1118            $$.qualifiers = NULL;
1119        }
1120    | ID '/' qbase
1121        {
1122            const struct frame *frame;
1123            struct frame_qual *qual;
1124
1125            $$ = $3;
1126            frame = find_frame($1);
1127            if (!frame) {
1128                yyerrorf("unknown frame \"%s\"", $1);
1129                YYABORT;
1130            } else {
1131                qual = alloc_type(struct frame_qual);
1132                qual->frame = frame;
1133                qual->next = $$.qualifiers;
1134                $$.qualifiers = qual;
1135            }
1136        }
1137    ;
1138
1139meas_type:
1140    TOK_MEAS
1141        {
1142            $$ = mt_xy_next;
1143        }
1144    | TOK_MEASX
1145        {
1146            $$ = mt_x_next;
1147        }
1148    | TOK_MEASY
1149        {
1150            $$ = mt_y_next;
1151        }
1152    ;
1153
1154meas_op:
1155    TOK_NEXT
1156        {
1157            $$.max = 0;
1158            $$.inverted = 0;
1159        }
1160    | TOK_NEXT_INVERTED
1161        {
1162            $$.max = 0;
1163            $$.inverted = 1;
1164        }
1165    | TOK_MAX
1166        {
1167            $$.max = 1;
1168            $$.inverted = 0;
1169        }
1170    | TOK_MAX_INVERTED
1171        {
1172            $$.max = 1;
1173            $$.inverted = 1;
1174        }
1175    ;
1176
1177opt_num:
1178        {
1179            $$.n = 0;
1180        }
1181    | NUMBER
1182        {
1183            $$ = $1;
1184        }
1185    ;
1186
1187opt_string:
1188        {
1189            $$ = NULL;
1190        }
1191    | STRING
1192        {
1193            $$ = $1;
1194        }
1195    ;
1196
1197opt_expr:
1198        {
1199            $$ = NULL;
1200        }
1201    | expr
1202        {
1203            $$ = $1;
1204        }
1205    ;
1206
1207expr:
1208    add_expr
1209        {
1210            $$ = $1;
1211        }
1212    ;
1213
1214add_expr:
1215    mult_expr
1216        {
1217            $$ = $1;
1218        }
1219    | add_expr '+' mult_expr
1220        {
1221            $$ = binary_op(op_add, $1, $3);
1222        }
1223    | add_expr '-' mult_expr
1224        {
1225            $$ = binary_op(op_sub, $1, $3);
1226        }
1227    ;
1228
1229mult_expr:
1230    unary_expr
1231        {
1232            $$ = $1;
1233        }
1234    | mult_expr '*' unary_expr
1235        {
1236            $$ = binary_op(op_mult, $1, $3);
1237        }
1238    | mult_expr '/' unary_expr
1239        {
1240            $$ = binary_op(op_div, $1, $3);
1241        }
1242    ;
1243
1244unary_expr:
1245    primary_expr
1246        {
1247            $$ = $1;
1248        }
1249    | '-' primary_expr
1250        {
1251            $$ = binary_op(op_minus, $2, NULL);
1252        }
1253    ;
1254
1255primary_expr:
1256    NUMBER
1257        {
1258            $$ = new_op(op_num);
1259            $$->u.num = $1;
1260        }
1261    | ID
1262        {
1263            $$ = new_op(op_var);
1264            $$->u.var = $1;
1265        }
1266    | STRING
1267        {
1268            $$ = new_op(op_string);
1269            $$->u.str = $1;
1270        }
1271    | '(' expr ')'
1272        {
1273            $$ = $2;
1274        }
1275    | ID '(' expr ')'
1276        {
1277            if ($1 == id_sin)
1278                $$ = binary_op(op_sin, $3, NULL);
1279            else if ($1 == id_cos)
1280                $$ = binary_op(op_cos, $3, NULL);
1281            else if ($1 == id_sqrt)
1282                $$ = binary_op(op_sqrt, $3, NULL);
1283            else if ($1 == id_floor)
1284                $$ = binary_op(op_floor, $3, NULL);
1285            else {
1286                yyerrorf("unknown function \"%s\"", $1);
1287                YYABORT;
1288            }
1289        }
1290    ;
1291
1292/* special sub-grammar */
1293
1294opt_value_list:
1295        {
1296            $$ = NULL;
1297        }
1298    | '=' row
1299        {
1300            $$ = $2;
1301        }
1302    ;
1303

Archive Download this file

Branches:
master



interactive