Root/fpd.y

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

Archive Download this file

Branches:
master



interactive