1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303 |
- %{
- /*
- * fpd.y - FootPrint Definition language
- *
- * Written 2009-2012 by Werner Almesberger
- * Copyright 2009-2012 by Werner Almesberger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
- #include <stdlib.h>
- #include <string.h>
- #include "util.h"
- #include "error.h"
- #include "coord.h"
- #include "expr.h"
- #include "obj.h"
- #include "meas.h"
- #include "gui_status.h"
- #include "gui_inst.h" /* for %meas */
- #include "dump.h"
- #include "tsort.h"
- #include "fpd.h"
- #include "y.tab.h"
- struct expr *expr_result;
- const char *var_id;
- struct value *var_value_list;
- static struct frame *curr_frame;
- static struct table *curr_table;
- static struct row *curr_row;
- static struct vec *last_vec = NULL;
- static struct table **next_table;
- static struct loop **next_loop;
- static struct vec **next_vec;
- static struct obj **next_obj;
- static int n_vars, n_values;
- static const char *id_sin, *id_cos, *id_sqrt, *id_floor;
- static struct tsort *tsort;
- /* ----- lookup functions -------------------------------------------------- */
- static struct frame *find_frame(const char *name)
- {
- struct frame *f;
- for (f = frames->next; f; f = f->next)
- if (f->name == name)
- return f;
- return NULL;
- }
- static struct vec *find_vec(const struct frame *frame, const char *name)
- {
- struct vec *v;
- for (v = frame->vecs; v; v = v->next)
- if (v->name == name)
- return v;
- return NULL;
- }
- static struct obj *find_obj(const struct frame *frame, const char *name)
- {
- struct obj *obj;
- for (obj = frame->objs; obj; obj = obj->next)
- if (obj->name == name)
- return obj;
- return NULL;
- }
- static int find_label(const struct frame *frame, const char *name)
- {
- if (find_vec(frame, name))
- return 1;
- if (find_obj(frame, name))
- return 1;
- return 0;
- }
- static struct var *find_var(const struct frame *frame, const char *name)
- {
- const struct table *table;
- struct var *var;
- struct loop *loop;
- for (table = frame->tables; table; table = table->next)
- for (var = table->vars; var; var = var->next)
- if (!var->key && var->name == name)
- return var;
- for (loop = frame->loops; loop; loop = loop->next)
- if (loop->var.name == name)
- return &loop->var;
- return NULL;
- }
- /* ----- item creation ----------------------------------------------------- */
- static void set_frame(struct frame *frame)
- {
- curr_frame = frame;
- next_table = &frame->tables;
- next_loop = &frame->loops;
- next_vec = &frame->vecs;
- next_obj = &frame->objs;
- last_vec = NULL;
- }
- static void make_var(const char *id, int key, struct expr *expr)
- {
- struct table *table;
- table = zalloc_type(struct table);
- table->vars = zalloc_type(struct var);
- table->vars->name = id;
- table->vars->frame = curr_frame;
- table->vars->table = table;
- table->vars->key = key;
- table->rows = zalloc_type(struct row);
- table->rows->table = table;
- table->rows->values = zalloc_type(struct value);
- table->rows->values->expr = expr;
- table->rows->values->row = table->rows;
- table->active_row = table->rows;
- *next_table = table;
- next_table = &table->next;
- }
- static void make_loop(const char *id, struct expr *from, struct expr *to)
- {
- struct loop *loop;
- loop = alloc_type(struct loop);
- loop->var.name = id;
- loop->var.next = NULL;
- loop->var.frame = curr_frame;
- loop->var.table = NULL;
- loop->from.expr = from;
- loop->from.row = NULL;
- loop->from.next = NULL;
- loop->to.expr = to;
- loop->to.row = NULL;
- loop->to.next = NULL;
- loop->next = NULL;
- loop->active = 0;
- loop->initialized = 0;
- *next_loop = loop;
- next_loop = &loop->next;
- }
- static struct obj *new_obj(enum obj_type type)
- {
- struct obj *obj;
- obj = alloc_type(struct obj);
- obj->type = type;
- obj->name = NULL;
- obj->frame = curr_frame;
- obj->next = NULL;
- obj->lineno = lineno;
- return obj;
- }
- /* ---- frame qualifiers --------------------------------------------------- */
- static int duplicate_qualifier(const struct frame_qual *a,
- const struct frame_qual *b)
- {
- if (!b)
- return 0;
- if (a != b && a->frame == b->frame) {
- yyerrorf("duplicate qualifier \"%s\"", a->frame->name);
- return 1;
- }
- if (b && duplicate_qualifier(a, b->next))
- return 1;
- return duplicate_qualifier(a->next, a->next);
- }
- static int can_reach(const struct frame *curr, const struct frame_qual *qual,
- const struct frame *end)
- {
- const struct obj *obj;
- if (curr == end)
- return !qual;
- /*
- * Don't recurse for removing the qualifier alone. We require a frame
- * reference step as well, so that things like foo.foo.foo.bar.vec
- * aren't allowed.
- *
- * Since a duplicate qualifier can never work, we test for this error
- * explicitly in "duplicate_qualifier".
- */
- if (qual && curr == qual->frame)
- qual = qual->next;
- for (obj = curr->objs; obj; obj = obj->next)
- if (obj->type == ot_frame)
- if (can_reach(obj->u.frame.ref, qual, end))
- return 1;
- return 0;
- }
- static int check_qbase(struct qbase *qbase)
- {
- if (duplicate_qualifier(qbase->qualifiers, qbase->qualifiers))
- return 0;
- if (!can_reach(frames, qbase->qualifiers, qbase->vec->frame))
- yywarn("not all qualifiers can be reached");
- return 1;
- }
- /* ----- debugging directives ---------------------------------------------- */
- static int dbg_delete(const char *frame_name, const char *name)
- {
- struct vec *vec;
- struct obj *obj;
- struct frame *frame;
- if (!frame_name) {
- frame = curr_frame;
- } else {
- frame = find_frame(frame_name);
- if (!frame) {
- yyerrorf("unknown frame \"%s\"", frame_name);
- return 0;
- }
- }
- vec = find_vec(frame, name);
- if (vec) {
- delete_vec(vec);
- return 1;
- }
- obj = find_obj(frame, name);
- if (obj) {
- delete_obj(obj);
- return 1;
- }
- if (!frame_name) {
- frame = find_frame(name);
- if (frame) {
- if (curr_frame == frame) {
- yyerrorf("a frame can't delete itself");
- return 0;
- }
- delete_frame(frame);
- return 1;
- }
- }
- if (frame_name)
- yyerrorf("unknown item \"%s.%s\"", frame_name, name);
- else
- yyerrorf("unknown item \"%s\"", name);
- return 0;
- }
- static int dbg_move(const char *name, int anchor, const char *dest)
- {
- struct vec *to, *vec;
- struct obj *obj;
- struct vec **anchors[3];
- int n_anchors;
- to = find_vec(curr_frame, dest);
- if (!to) {
- yyerrorf("unknown vector \"%s\"", dest);
- return 0;
- }
- vec = find_vec(curr_frame, name);
- if (vec) {
- if (anchor) {
- yyerrorf("invalid anchor (%d > 0)", anchor);
- return 0;
- }
- vec->base = to;
- return 1;
- }
- obj = find_obj(curr_frame, name);
- if (!obj) {
- yyerrorf("unknown item \"%s\"", name);
- return 0;
- }
- n_anchors = obj_anchors(obj, anchors);
- if (anchor >= n_anchors) {
- yyerrorf("invalid anchor (%d > %d)", anchor, n_anchors-1);
- return 0;
- }
- *anchors[anchor] = to;
- return 1;
- }
- /*
- * @@@ This is very similar to what we do in rule "obj". Consider merging.
- */
- /*
- * We need to pass base_frame and base_vec, not just the vector (with the
- * frame implied) since we can also reference the frame's origin, whose
- * "vector" is NULL.
- */
- static int dbg_link_frame(const char *frame_name,
- struct frame *base_frame, struct vec *base_vec)
- {
- struct frame *frame;
- struct obj *obj;
- assert(!base_vec || base_vec->frame == base_frame);
- frame = find_frame(frame_name);
- if (!frame) {
- yyerrorf("unknown frame \"%s\"", frame_name);
- return 0;
- }
- /* this can only fail in %frame */
- if (is_parent_of(frame, base_frame)) {
- yyerrorf("frame \"%s\" is a parent of \"%s\"",
- frame->name, base_frame->name);
- return 0;
- }
- obj = new_obj(ot_frame);
- obj->base = base_vec;
- obj->frame = base_frame;
- obj->u.frame.ref = frame;
- connect_obj(base_frame, obj);
- if (!frame->active_ref)
- frame->active_ref = obj;
- return 1;
- }
- int dbg_print(const struct expr *expr, const struct frame *frame)
- {
- const char *s;
- struct num num;
- s = eval_str(expr, frame);
- if (s) {
- printf("%s\n", s);
- return 1;
- }
- num = eval_num(expr, frame);
- if (is_undef(num))
- return 0;
- printf("%lg%s\n", num.n, str_unit(num));
- return 1;
- }
- static int dbg_meas(const char *name)
- {
- const struct obj *obj;
- const struct inst *inst;
- struct coord a1, b1;
- char *s;
- obj = find_obj(frames, name);
- if (!obj) {
- yyerrorf("unknown object \"%s\"", name);
- return 0;
- }
- /* from fped.c:main */
- if (!pkg_name)
- pkg_name = stralloc("_");
- reporter = report_to_stderr;
- if (!instantiate())
- return 0;
- inst = find_meas_hint(obj);
- if (!inst) {
- yyerrorf("measurement \"%s\" was not instantiated", name);
- return 0;
- }
- project_meas(inst, &a1, &b1);
- s = format_len(obj->u.meas.label ? obj->u.meas.label : "",
- dist_point(a1, b1), curr_unit);
- printf("%s\n", s);
- free(s);
- return 1;
- }
- %}
- %union {
- struct num num;
- int flag;
- char *str;
- const char *id;
- struct expr *expr;
- struct frame *frame;
- struct table *table;
- struct var *var;
- struct row *row;
- struct value *value;
- struct vec *vec;
- struct obj *obj;
- enum pad_type pt;
- enum meas_type mt;
- struct {
- int inverted;
- int max;
- } mo;
- struct {
- struct frame *frame;
- struct vec *vec;
- } qvec;
- struct qbase {
- struct vec *vec;
- struct frame_qual *qualifiers;
- } qbase;
- };
- %token START_FPD START_EXPR START_VAR START_VALUES
- %token TOK_SET TOK_LOOP TOK_PACKAGE TOK_FRAME TOK_TABLE TOK_VEC
- %token TOK_PAD TOK_RPAD TOK_HOLE TOK_RECT TOK_LINE TOK_CIRC TOK_ARC
- %token TOK_MEAS TOK_MEASX TOK_MEASY TOK_UNIT
- %token TOK_NEXT TOK_NEXT_INVERTED TOK_MAX TOK_MAX_INVERTED
- %token TOK_DBG_DEL TOK_DBG_MOVE TOK_DBG_FRAME
- %token TOK_DBG_PRINT TOK_DBG_IPRINT
- %token TOK_DBG_DUMP TOK_DBG_EXIT TOK_DBG_TSORT TOK_DBG_MEAS
- %token TOK_ALLOW_HOLES TOK_ALLOW_OVERLAP TOK_ALLOW_TOUCH
- %token <num> NUMBER
- %token <str> STRING
- %token <id> ID LABEL
- %type <table> table
- %type <var> vars var
- %type <row> rows
- %type <value> row value opt_value_list
- %type <vec> vec base
- %type <obj> object obj meas unlabeled_meas
- %type <expr> expr opt_expr add_expr mult_expr unary_expr primary_expr
- %type <num> opt_num
- %type <flag> opt_key
- %type <frame> frame_qualifier
- %type <str> opt_string
- %type <pt> pad_type
- %type <mt> meas_type
- %type <mo> meas_op
- %type <qvec> qualified_base
- %type <qbase> qbase qbase_unchecked
- %%
- all:
- START_FPD
- {
- frames = zalloc_type(struct frame);
- set_frame(frames);
- id_sin = unique("sin");
- id_cos = unique("cos");
- id_sqrt = unique("sqrt");
- id_floor = unique("floor");
- }
- fpd
- | START_EXPR expr
- {
- expr_result = $2;
- }
- | START_VAR ID opt_value_list
- {
- var_id = $2;
- var_value_list = $3;
- }
- | START_VALUES row
- {
- var_value_list = $2;
- }
- ;
- fpd:
- frame_defs part_name opt_setup opt_frame_items opt_measurements
- | frame_defs setup opt_frame_items opt_measurements
- | frame_defs frame_items opt_measurements
- | frame_defs opt_measurements
- ;
- part_name:
- TOK_PACKAGE STRING
- {
- const char *p;
- if (!*$2) {
- yyerrorf("invalid package name");
- YYABORT;
- }
- for (p = $2; *p; *p++)
- if (*p < 32 || *p > 126) {
- yyerrorf("invalid package name");
- YYABORT;
- }
- pkg_name = $2;
- }
- ;
- opt_setup:
- | setup
- ;
- setup:
- unit
- | allow_pads
- | allow_holes
- | unit allow_pads
- | unit allow_pads allow_holes
- | unit allow_holes
- | unit allow_holes allow_pads
- | allow_pads unit
- | allow_pads unit allow_holes
- | allow_holes unit
- | allow_holes unit allow_pads
- ;
- unit:
- TOK_UNIT ID
- {
- if (!strcmp($2, "mm"))
- curr_unit = curr_unit_mm;
- else if (!strcmp($2, "mil"))
- curr_unit = curr_unit_mil;
- else if (!strcmp($2, "auto"))
- curr_unit = curr_unit_auto;
- else {
- yyerrorf("unrecognized unit \"%s\"", $2);
- YYABORT;
- }
- }
- ;
- allow_pads:
- TOK_ALLOW_TOUCH
- {
- allow_overlap = ao_touch;
- }
- | TOK_ALLOW_OVERLAP
- {
- allow_overlap = ao_any;
- }
- ;
- allow_holes:
- TOK_ALLOW_HOLES
- {
- holes_linked = 0;
- }
- ;
- frame_defs:
- | frame_defs frame_def
- ;
- frame_def:
- TOK_FRAME ID '{'
- {
- if (find_frame($2)) {
- yyerrorf("duplicate frame \"%s\"", $2);
- YYABORT;
- }
- curr_frame = zalloc_type(struct frame);
- curr_frame->name = $2;
- set_frame(curr_frame);
- curr_frame->next = frames->next;
- frames->next = curr_frame;
- }
- opt_frame_items '}'
- {
- set_frame(frames);
- }
- ;
- opt_frame_items:
- | frame_items
- ;
- frame_items:
- frame_item
- | frame_item frame_items
- ;
- frame_item:
- table
- | TOK_SET opt_key ID '=' expr
- {
- if (!$2 && find_var(curr_frame, $3)) {
- yyerrorf("duplicate variable \"%s\"", $3);
- YYABORT;
- }
- make_var($3, $2, $5);
- }
- | TOK_LOOP ID '=' expr ',' expr
- {
- if (find_var(curr_frame, $2)) {
- yyerrorf("duplicate variable \"%s\"", $2);
- YYABORT;
- }
- make_loop($2, $4, $6);
- }
- | vec
- | LABEL vec
- {
- if (find_label(curr_frame, $1)) {
- yyerrorf("duplicate label \"%s\"", $1);
- YYABORT;
- }
- $2->name = $1;
- }
- | object
- | LABEL object
- {
- if (find_label(curr_frame, $1)) {
- yyerrorf("duplicate label \"%s\"", $1);
- YYABORT;
- }
- $2->name = $1;
- }
- | debug_item
- ;
- debug_item:
- TOK_DBG_DEL ID
- {
- if (!dbg_delete(NULL, $2))
- YYABORT;
- }
- | TOK_DBG_DEL ID '.' ID
- {
- if (!dbg_delete($2, $4))
- YYABORT;
- }
- | TOK_DBG_MOVE ID opt_num ID
- {
- if (!dbg_move($2, $3.n, $4))
- YYABORT;
- }
- | TOK_DBG_FRAME ID qualified_base
- {
- if (!dbg_link_frame($2, $3.frame, $3.vec))
- YYABORT;
- }
- | TOK_DBG_PRINT expr
- {
- if (!dbg_print($2, curr_frame))
- YYABORT;
- }
- | TOK_DBG_MEAS ID
- {
- if (!dbg_meas($2))
- YYABORT;
- }
- | TOK_DBG_DUMP
- {
- if (!dump(stdout, NULL)) {
- perror("stdout");
- exit(1);
- }
- }
- | TOK_DBG_EXIT
- {
- exit(0);
- }
- | TOK_DBG_TSORT '{'
- {
- tsort = begin_tsort();
- }
- sort_items '}'
- {
- void **sort, **walk;
- sort = end_tsort(tsort);
- for (walk = sort; *walk; walk++)
- printf("%s\n", (char *) *walk);
- free(sort);
- }
- ;
- sort_items:
- | sort_items '+' ID
- {
- add_node(tsort, (void *) $3, 0);
- }
- | sort_items '-' ID
- {
- add_node(tsort, (void *) $3, 1);
- }
- | sort_items ID ID opt_num
- {
- struct node *a, *b;
- /* order is important here ! */
- a = add_node(tsort, (void *) $2, 0);
- b = add_node(tsort, (void *) $3, 0);
- add_edge(a, b, $4.n);
- }
- ;
- table:
- TOK_TABLE
- {
- $<table>$ = zalloc_type(struct table);
- *next_table = $<table>$;
- curr_table = $<table>$;
- n_vars = 0;
- }
- '{' vars '}' rows
- {
- $$ = $<table>2;
- $$->vars = $4;
- $$->rows = $6;
- $$->active_row = $6;
- next_table = &$$->next;
- }
- ;
- vars:
- var
- {
- $$ = $1;
- }
- | vars ',' var
- {
- struct var **walk;
- $$ = $1;
- for (walk = &$$; *walk; walk = &(*walk)->next);
- *walk = $3;
- }
- ;
- var:
- opt_key ID
- {
- if (!$1 && find_var(curr_frame, $2)) {
- yyerrorf("duplicate variable \"%s\"", $2);
- YYABORT;
- }
- $$ = zalloc_type(struct var);
- $$->name = $2;
- $$->frame = curr_frame;
- $$->table = curr_table;
- $$->key = $1;
- $$->next = NULL;
- n_vars++;
- }
- ;
- opt_key:
- {
- $$ = 0;
- }
- | '?'
- {
- $$ = 1;
- }
- ;
- rows:
- {
- $$ = NULL;
- }
- | '{'
- {
- $<row>$ = alloc_type(struct row);
- $<row>$->table = curr_table;
- curr_row = $<row>$;;
- n_values = 0;
- }
- row '}'
- {
- if (n_vars != n_values) {
- yyerrorf("table has %d variables but row has "
- "%d values", n_vars, n_values);
- YYABORT;
- }
- $<row>2->values = $3;
- }
- rows
- {
- $$ = $<row>2;
- $$->next = $6;
- }
- ;
- row:
- value
- {
- $$ = $1;
- }
- | row ',' value
- {
- struct value **walk;
- $$ = $1;
- for (walk = &$$; *walk; walk = &(*walk)->next);
- *walk = $3;
- }
- ;
- value:
- expr
- {
- $$ = alloc_type(struct value);
- $$->expr = $1;
- $$->row = curr_row;
- $$->next = NULL;
- n_values++;
- }
- ;
- vec:
- TOK_VEC base '(' expr ',' expr ')'
- {
- $$ = alloc_type(struct vec);
- $$->nul_tag = 0;
- $$->name = NULL;
- $$->base = $2;
- $$->x = $4;
- $$->y = $6;
- $$->frame = curr_frame;
- $$->next = NULL;
- last_vec = $$;
- *next_vec = $$;
- next_vec = &$$->next;
- }
- ;
- base:
- '@'
- {
- $$ = NULL;
- }
- | '.'
- {
- $$ = last_vec;
- if (!$$) {
- yyerrorf(". without predecessor");
- YYABORT;
- }
- }
- | ID
- {
- $$ = find_vec(curr_frame, $1);
- if (!$$)
- $$ = (struct vec *) $1;
- }
- ;
- qualified_base:
- base
- {
- $$.frame = curr_frame;
- $$.vec = $1;
- }
- | frame_qualifier '@'
- {
- $$.frame = $1;
- $$.vec = NULL;
- }
- | frame_qualifier ID
- {
- $$.frame = $1;
- $$.vec = find_vec($1, $2);
- if (!$$.vec) {
- yyerrorf("unknown vector \"%s.%s\"",
- $1->name, $2);
- YYABORT;
- }
- }
- ;
- frame_qualifier:
- ID '.'
- {
- $$ = find_frame($1);
- if (!$$) {
- yyerrorf("unknown frame \"%s\"", $1);
- YYABORT;
- }
- }
- ;
- object:
- obj
- {
- $$ = $1;
- *next_obj = $1;
- next_obj = &$1->next;
- }
- ;
- obj:
- TOK_PAD STRING base base pad_type
- {
- $$ = new_obj(ot_pad);
- $$->base = $3;
- $$->u.pad.name = $2;
- $$->u.pad.other = $4;
- $$->u.pad.rounded = 0;
- $$->u.pad.type = $5;
- }
- | TOK_RPAD STRING base base pad_type
- {
- $$ = new_obj(ot_pad);
- $$->base = $3;
- $$->u.pad.name = $2;
- $$->u.pad.other = $4;
- $$->u.pad.rounded = 1;
- $$->u.pad.type = $5;
- }
- | TOK_HOLE base base
- {
- $$ = new_obj(ot_hole);
- $$->base = $2;
- $$->u.hole.other = $3;
- }
- | TOK_RECT base base opt_expr
- {
- $$ = new_obj(ot_rect);
- $$->base = $2;
- $$->u.rect.other = $3;
- $$->u.rect.width = $4;
- }
- | TOK_LINE base base opt_expr
- {
- $$ = new_obj(ot_line);
- $$->base = $2;
- $$->u.line.other = $3;
- $$->u.line.width = $4;
- }
- | TOK_CIRC base base opt_expr
- {
- $$ = new_obj(ot_arc);
- $$->base = $2;
- $$->u.arc.start = $3;
- $$->u.arc.end = $3;
- $$->u.arc.width = $4;
- }
- | TOK_ARC base base base opt_expr
- {
- $$ = new_obj(ot_arc);
- $$->base = $2;
- $$->u.arc.start = $3;
- $$->u.arc.end = $4;
- $$->u.arc.width = $5;
- }
- | TOK_FRAME ID
- {
- $<num>$.n = lineno;
- }
- base
- {
- $$ = new_obj(ot_frame);
- $$->base = $4;
- $$->u.frame.ref = find_frame($2);
- if (!$$->u.frame.ref) {
- yyerrorf("unknown frame \"%s\"", $2);
- YYABORT;
- }
- if (!$$->u.frame.ref->active_ref)
- $$->u.frame.ref->active_ref = $$;
- $$->u.frame.lineno = $<num>3.n;
- }
- | TOK_DBG_IPRINT expr
- {
- $$ = new_obj(ot_iprint);
- $$->base = NULL;
- $$->u.iprint.expr = $2;
- }
- ;
- pad_type:
- {
- $$ = pt_normal;
- }
- | ID
- {
- if (!strcmp($1, "bare"))
- $$ = pt_bare;
- else if (!strcmp($1, "trace"))
- $$ = pt_trace;
- else if (!strcmp($1, "paste"))
- $$ = pt_paste;
- else if (!strcmp($1, "mask"))
- $$ = pt_mask;
- else {
- yyerrorf("unknown pad type \"%s\"", $1);
- YYABORT;
- }
- }
- ;
- opt_measurements:
- | measurements
- ;
- measurements:
- unlabeled_meas /* @@@ hack */
- {
- *next_obj = $1;
- next_obj = &$1->next;
- }
- | measurements meas
- {
- *next_obj = $2;
- next_obj = &$2->next;
- }
- | measurements debug_item
- ;
- meas:
- unlabeled_meas
- {
- $$ = $1;
- }
- | LABEL unlabeled_meas
- {
- $$ = $2;
- if (find_label(curr_frame, $1)) {
- yyerrorf("duplicate label \"%s\"", $1);
- YYABORT;
- }
- $$->name = $1;
- }
- ;
- unlabeled_meas:
- meas_type opt_string qbase meas_op qbase opt_expr
- {
- struct meas *meas;
- $$ = new_obj(ot_meas);
- meas = &$$->u.meas;
- meas->type = $4.max ? $1+3 : $1;
- meas->label = $2;
- $$->base = $3.vec;
- meas->low_qual = $3.qualifiers;
- meas->inverted = $4.inverted;
- meas->high = $5.vec;
- meas->high_qual = $5.qualifiers;
- meas->offset = $6;
- $$->next = NULL;
- }
- ;
- qbase:
- qbase_unchecked
- {
- $$ = $1;
- if (!check_qbase(&$$))
- YYABORT;
- }
- ;
- qbase_unchecked:
- ID
- {
- $$.vec = find_vec(frames, $1);
- if (!$$.vec) {
- yyerrorf("unknown vector \"%s\"", $1);
- YYABORT;
- }
- $$.qualifiers = NULL;
- }
- | ID '.' ID
- {
- const struct frame *frame;
- frame = find_frame($1);
- $$.vec = frame ? find_vec(frame, $3) : NULL;
- if (!$$.vec) {
- yyerrorf("unknown vector \"%s.%s\"", $1, $3);
- YYABORT;
- }
- $$.qualifiers = NULL;
- }
- | ID '/' qbase
- {
- const struct frame *frame;
- struct frame_qual *qual;
- $$ = $3;
- frame = find_frame($1);
- if (!frame) {
- yyerrorf("unknown frame \"%s\"", $1);
- YYABORT;
- } else {
- qual = alloc_type(struct frame_qual);
- qual->frame = frame;
- qual->next = $$.qualifiers;
- $$.qualifiers = qual;
- }
- }
- ;
- meas_type:
- TOK_MEAS
- {
- $$ = mt_xy_next;
- }
- | TOK_MEASX
- {
- $$ = mt_x_next;
- }
- | TOK_MEASY
- {
- $$ = mt_y_next;
- }
- ;
- meas_op:
- TOK_NEXT
- {
- $$.max = 0;
- $$.inverted = 0;
- }
- | TOK_NEXT_INVERTED
- {
- $$.max = 0;
- $$.inverted = 1;
- }
- | TOK_MAX
- {
- $$.max = 1;
- $$.inverted = 0;
- }
- | TOK_MAX_INVERTED
- {
- $$.max = 1;
- $$.inverted = 1;
- }
- ;
- opt_num:
- {
- $$.n = 0;
- }
- | NUMBER
- {
- $$ = $1;
- }
- ;
- opt_string:
- {
- $$ = NULL;
- }
- | STRING
- {
- $$ = $1;
- }
- ;
- opt_expr:
- {
- $$ = NULL;
- }
- | expr
- {
- $$ = $1;
- }
- ;
- expr:
- add_expr
- {
- $$ = $1;
- }
- ;
- add_expr:
- mult_expr
- {
- $$ = $1;
- }
- | add_expr '+' mult_expr
- {
- $$ = binary_op(op_add, $1, $3);
- }
- | add_expr '-' mult_expr
- {
- $$ = binary_op(op_sub, $1, $3);
- }
- ;
- mult_expr:
- unary_expr
- {
- $$ = $1;
- }
- | mult_expr '*' unary_expr
- {
- $$ = binary_op(op_mult, $1, $3);
- }
- | mult_expr '/' unary_expr
- {
- $$ = binary_op(op_div, $1, $3);
- }
- ;
- unary_expr:
- primary_expr
- {
- $$ = $1;
- }
- | '-' primary_expr
- {
- $$ = binary_op(op_minus, $2, NULL);
- }
- ;
- primary_expr:
- NUMBER
- {
- $$ = new_op(op_num);
- $$->u.num = $1;
- }
- | ID
- {
- $$ = new_op(op_var);
- $$->u.var = $1;
- }
- | STRING
- {
- $$ = new_op(op_string);
- $$->u.str = $1;
- }
- | '(' expr ')'
- {
- $$ = $2;
- }
- | ID '(' expr ')'
- {
- if ($1 == id_sin)
- $$ = binary_op(op_sin, $3, NULL);
- else if ($1 == id_cos)
- $$ = binary_op(op_cos, $3, NULL);
- else if ($1 == id_sqrt)
- $$ = binary_op(op_sqrt, $3, NULL);
- else if ($1 == id_floor)
- $$ = binary_op(op_floor, $3, NULL);
- else {
- yyerrorf("unknown function \"%s\"", $1);
- YYABORT;
- }
- }
- ;
- /* special sub-grammar */
- opt_value_list:
- {
- $$ = NULL;
- }
- | '=' row
- {
- $$ = $2;
- }
- ;
|