📄 pic.y
字号:
{ $$ = new object_spec(CIRCLE_OBJECT); } | ELLIPSE { $$ = new object_spec(ELLIPSE_OBJECT); } | ARC { $$ = new object_spec(ARC_OBJECT); $$->dir = current_direction; } | LINE { $$ = new object_spec(LINE_OBJECT); lookup_variable("lineht", & $$->segment_height); lookup_variable("linewid", & $$->segment_width); $$->dir = current_direction; } | ARROW { $$ = new object_spec(ARROW_OBJECT); lookup_variable("lineht", & $$->segment_height); lookup_variable("linewid", & $$->segment_width); $$->dir = current_direction; } | MOVE { $$ = new object_spec(MOVE_OBJECT); lookup_variable("moveht", & $$->segment_height); lookup_variable("movewid", & $$->segment_width); $$->dir = current_direction; } | SPLINE { $$ = new object_spec(SPLINE_OBJECT); lookup_variable("lineht", & $$->segment_height); lookup_variable("linewid", & $$->segment_width); $$->dir = current_direction; } | text %prec TEXT { $$ = new object_spec(TEXT_OBJECT); $$->text = new text_item($1.str, $1.filename, $1.lineno); } | PLOT expr { $$ = new object_spec(TEXT_OBJECT); $$->text = new text_item(format_number(0, $2), 0, -1); } | PLOT expr text { $$ = new object_spec(TEXT_OBJECT); $$->text = new text_item(format_number($3.str, $2), $3.filename, $3.lineno); a_delete $3.str; } | '[' { saved_state *p = new saved_state; $<pstate>$ = p; p->x = current_position.x; p->y = current_position.y; p->dir = current_direction; p->tbl = current_table; p->prev = current_saved_state; current_position.x = 0.0; current_position.y = 0.0; current_table = new PTABLE(place); current_saved_state = p; olist.append(make_mark_object()); } element_list ']' { current_position.x = $<pstate>2->x; current_position.y = $<pstate>2->y; current_direction = $<pstate>2->dir; $$ = new object_spec(BLOCK_OBJECT); olist.wrap_up_block(& $$->oblist); $$->tbl = current_table; current_table = $<pstate>2->tbl; current_saved_state = $<pstate>2->prev; delete $<pstate>2; } | object_spec HEIGHT expr { $$ = $1; $$->height = $3; $$->flags |= HAS_HEIGHT; } | object_spec RADIUS expr { $$ = $1; $$->radius = $3; $$->flags |= HAS_RADIUS; } | object_spec WIDTH expr { $$ = $1; $$->width = $3; $$->flags |= HAS_WIDTH; } | object_spec DIAMETER expr { $$ = $1; $$->radius = $3/2.0; $$->flags |= HAS_RADIUS; } | object_spec expr %prec HEIGHT { $$ = $1; $$->flags |= HAS_SEGMENT; switch ($$->dir) { case UP_DIRECTION: $$->segment_pos.y += $2; break; case DOWN_DIRECTION: $$->segment_pos.y -= $2; break; case RIGHT_DIRECTION: $$->segment_pos.x += $2; break; case LEFT_DIRECTION: $$->segment_pos.x -= $2; break; } } | object_spec UP { $$ = $1; $$->dir = UP_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.y += $$->segment_height; } | object_spec UP expr { $$ = $1; $$->dir = UP_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.y += $3; } | object_spec DOWN { $$ = $1; $$->dir = DOWN_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.y -= $$->segment_height; } | object_spec DOWN expr { $$ = $1; $$->dir = DOWN_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.y -= $3; } | object_spec RIGHT { $$ = $1; $$->dir = RIGHT_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.x += $$->segment_width; } | object_spec RIGHT expr { $$ = $1; $$->dir = RIGHT_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.x += $3; } | object_spec LEFT { $$ = $1; $$->dir = LEFT_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.x -= $$->segment_width; } | object_spec LEFT expr { $$ = $1; $$->dir = LEFT_DIRECTION; $$->flags |= HAS_SEGMENT; $$->segment_pos.x -= $3; } | object_spec FROM position { $$ = $1; $$->flags |= HAS_FROM; $$->from.x = $3.x; $$->from.y = $3.y; } | object_spec TO position { $$ = $1; if ($$->flags & HAS_SEGMENT) $$->segment_list = new segment($$->segment_pos, $$->segment_is_absolute, $$->segment_list); $$->flags |= HAS_SEGMENT; $$->segment_pos.x = $3.x; $$->segment_pos.y = $3.y; $$->segment_is_absolute = 1; $$->flags |= HAS_TO; $$->to.x = $3.x; $$->to.y = $3.y; } | object_spec AT position { $$ = $1; $$->flags |= HAS_AT; $$->at.x = $3.x; $$->at.y = $3.y; if ($$->type != ARC_OBJECT) { $$->flags |= HAS_FROM; $$->from.x = $3.x; $$->from.y = $3.y; } } | object_spec WITH path { $$ = $1; $$->flags |= HAS_WITH; $$->with = $3; } | object_spec BY expr_pair { $$ = $1; $$->flags |= HAS_SEGMENT; $$->segment_pos.x += $3.x; $$->segment_pos.y += $3.y; } | object_spec THEN { $$ = $1; if ($$->flags & HAS_SEGMENT) { $$->segment_list = new segment($$->segment_pos, $$->segment_is_absolute, $$->segment_list); $$->flags &= ~HAS_SEGMENT; $$->segment_pos.x = $$->segment_pos.y = 0.0; $$->segment_is_absolute = 0; } } | object_spec DOTTED { $$ = $1; $$->flags |= IS_DOTTED; lookup_variable("dashwid", & $$->dash_width); } | object_spec DOTTED expr { $$ = $1; $$->flags |= IS_DOTTED; $$->dash_width = $3; } | object_spec DASHED { $$ = $1; $$->flags |= IS_DASHED; lookup_variable("dashwid", & $$->dash_width); } | object_spec DASHED expr { $$ = $1; $$->flags |= IS_DASHED; $$->dash_width = $3; } | object_spec FILL { $$ = $1; $$->flags |= IS_DEFAULT_FILLED; } | object_spec FILL expr { $$ = $1; $$->flags |= IS_FILLED; $$->fill = $3; } | object_spec CHOP { $$ = $1; // line chop chop means line chop 0 chop 0 if ($$->flags & IS_DEFAULT_CHOPPED) { $$->flags |= IS_CHOPPED; $$->flags &= ~IS_DEFAULT_CHOPPED; $$->start_chop = $$->end_chop = 0.0; } else if ($$->flags & IS_CHOPPED) { $$->end_chop = 0.0; } else { $$->flags |= IS_DEFAULT_CHOPPED; } } | object_spec CHOP expr { $$ = $1; if ($$->flags & IS_DEFAULT_CHOPPED) { $$->flags |= IS_CHOPPED; $$->flags &= ~IS_DEFAULT_CHOPPED; $$->start_chop = 0.0; $$->end_chop = $3; } else if ($$->flags & IS_CHOPPED) { $$->end_chop = $3; } else { $$->start_chop = $$->end_chop = $3; $$->flags |= IS_CHOPPED; } } | object_spec SAME { $$ = $1; $$->flags |= IS_SAME; } | object_spec INVISIBLE { $$ = $1; $$->flags |= IS_INVISIBLE; } | object_spec LEFT_ARROW_HEAD { $$ = $1; $$->flags |= HAS_LEFT_ARROW_HEAD; } | object_spec RIGHT_ARROW_HEAD { $$ = $1; $$->flags |= HAS_RIGHT_ARROW_HEAD; } | object_spec DOUBLE_ARROW_HEAD { $$ = $1; $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); } | object_spec CW { $$ = $1; $$->flags |= IS_CLOCKWISE; } | object_spec CCW { $$ = $1; $$->flags &= ~IS_CLOCKWISE; } | object_spec text %prec TEXT { $$ = $1; for (text_item **p = & $$->text; *p; p = &(*p)->next) ; *p = new text_item($2.str, $2.filename, $2.lineno); } | object_spec LJUST { $$ = $1; if ($$->text) { for (text_item *p = $$->text; p->next; p = p->next) ; p->adj.h = LEFT_ADJUST; } } | object_spec RJUST { $$ = $1; if ($$->text) { for (text_item *p = $$->text; p->next; p = p->next) ; p->adj.h = RIGHT_ADJUST; } } | object_spec ABOVE { $$ = $1; if ($$->text) { for (text_item *p = $$->text; p->next; p = p->next) ; p->adj.v = ABOVE_ADJUST; } } | object_spec BELOW { $$ = $1; if ($$->text) { for (text_item *p = $$->text; p->next; p = p->next) ; p->adj.v = BELOW_ADJUST; } } | object_spec THICKNESS expr { $$ = $1; $$->flags |= HAS_THICKNESS; $$->thickness = $3; } | object_spec ALIGNED { $$ = $1; $$->flags |= IS_ALIGNED; } ;text: TEXT { $$ = $1; } | SPRINTF '(' TEXT sprintf_args ')' { $$.filename = $3.filename; $$.lineno = $3.lineno; $$.str = do_sprintf($3.str, $4.v, $4.nv); a_delete $4.v; a_delete $3.str; } ;sprintf_args: /* empty */ { $$.v = 0; $$.nv = 0; $$.maxv = 0; } | sprintf_args ',' expr { $$ = $1; if ($$.nv >= $$.maxv) { if ($$.nv == 0) { $$.v = new double[4]; $$.maxv = 4; } else { double *oldv = $$.v; $$.maxv *= 2; $$.v = new double[$$.maxv]; memcpy($$.v, oldv, $$.nv*sizeof(double)); a_delete oldv; } } $$.v[$$.nv] = $3; $$.nv += 1; } ;position: position_not_place { $$ = $1; } | place { position pos = $1; $$.x = pos.x; $$.y = pos.y; } ;position_not_place: expr_pair { $$ = $1; } | position '+' expr_pair { $$.x = $1.x + $3.x; $$.y = $1.y + $3.y; } | position '-' expr_pair { $$.x = $1.x - $3.x; $$.y = $1.y - $3.y; } | '(' position ',' position ')' { $$.x = $2.x; $$.y = $4.y; } | expr between position AND position { $$.x = (1.0 - $1)*$3.x + $1*$5.x; $$.y = (1.0 - $1)*$3.y + $1*$5.y; } | expr '<' position ',' position '>' { $$.x = (1.0 - $1)*$3.x + $1*$5.x; $$.y = (1.0 - $1)*$3.y + $1*$5.y; } ;between: BETWEEN | OF THE WAY BETWEEN ;expr_pair: expr ',' expr { $$.x = $1; $$.y = $3; } | '(' expr_pair ')' { $$ = $2; } ;place: label %prec CHOP /* line at A left == line (at A) left */ { $$ = $1; } | label corner { path pth($2); if (!pth.follow($1, & $$)) YYABORT; } | corner label { path pth($1); if (!pth.follow($2, & $$)) YYABORT; } | corner OF label { path pth($1); if (!pth.follow($3, & $$)) YYABORT; } | HERE { $$.x = current_position.x; $$.y = current_position.y; $$.obj = 0; } ;label: LABEL { place *p = lookup_label($1); if (!p) { lex_error("there is no place `%1'", $1); YYABORT; } $$ = *p; a_delete $1; } | nth_primitive { $$.obj = $1; } | label '.' LABEL { path pth($3); if (!pth.follow($1, & $$)) YYABORT; } ;ordinal: ORDINAL { $$ = $1; } | '`' any_expr TH { // XXX Check for overflow (and non-integers?). $$ = (int)$2; } ;optional_ordinal_last: LAST { $$ = 1; } | ordinal LAST { $$ = $1; } ;nth_primitive: ordinal object_type { int count = 0; for (object *p = olist.head; p != 0; p = p->next) if (p->type() == $2 && ++count == $1) { $$ = p; break; } if (p == 0) { lex_error("there is no %1%2 %3", $1, ordinal_postfix($1), object_type_name($2)); YYABORT; } } | optional_ordinal_last object_type { int count = 0; for (object *p = olist.tail; p != 0; p = p->prev) if (p->type() == $2 && ++count == $1) { $$ = p; break; } if (p == 0) { lex_error("there is no %1%2 last %3", $1, ordinal_postfix($1), object_type_name($2)); YYABORT; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -