1# Pikchr Grammar 2 3This file describes the grammar of the input files to Pikchr. Keywords 4and operators are shown in **bold**. Non-terminal symbols are shown 5in *italic*. Special token classes are shown in ALL-CAPS. A grammar 6symbol followed by "*" means zero-or-more. A grammar symbol 7followed by "?" means zero-or-one. Parentheses are used for grouping. 8Two grammar symbols within "(..|..)" means one or the other. 9 Marks of the form 10"[▶info](./grammar.md)" are links to more information and are 11not part of the grammar. 12 13The following special token classes are recognized: 14 15 * NEWLINE → A un-escaped newline character, U+000A. 16 A backslash followed by zero or more whitespace characters 17 and then a U+000A character is interpreted as ordinary whitespace, 18 not as a NEWLINE. 19 20 * LABEL → An object or place label starting with an 21 upper-case ASCII letter and continuing with zero or more 22 ASCII letters, digits, and/or underscores. A LABEL always starts 23 with an upper-case letter. 24 25 * VARIABLE → A variable name consisting of a lower-case 26 ASCII letter or "$" or "@" and followed by zero or more 27 ASCII letters, digits, and/or underscores. VARIABLEs may 28 contain upper-case letters, but they never begin with an upper-case. 29 In this way, VARIABLEs are distinct from LABELs. 30 31 * NUMBER → A numeric literal. The value can be a decimal 32 integer, a floating point value, or a hexadecimal literal 33 starting with "0x". Decimal and floating point values can 34 optionally be followed by a two-character unit designator that is 35 one of: "in", "cm", "px", "pt", "pc", or "mm". There can be 36 no whitespace in between the numeric portion of the constant and 37 the unit. 38 39 * ORDINAL → A non-zero integer literal followed by one of the 40 suffixes "st", "nd", "rd", or "th". Examples: "1st", "2nd", 41 "3rd", "4th", "5th", and so forth. As a special case, "first" 42 is accepted as an alternative spelling of "1st". 43 44 * STRING → A string literal that begins and ends with 45 double-quotes (U+0022). Within the string literal, a double-quote 46 character can be escaped using backslash (U+005c). A backslash 47 can also be used to escape a backslash. No other escape sequences 48 are recognized. 49 50 * COLORNAME → One of the 140 official HTML color names, in 51 any mixture of upper and lower cases. The value of a COLORNAME is 52 an integer which is the 24-bit RGB value of that color. Two 53 additional color names of "None" and "Off" are also recognized and 54 have a value of -1. 55 56 * CODEBLOCK → All tokens contained within nested {...}. This 57 is only used as the body of a "define" statement. 58 59There are many non-terminals in the grammar, but a few are more important. 60If you are new to the Pikchr language, begin by focusing on these 61six: 62 63 * *statement* → A Pikchr script is just a list of statements. 64 65 * *attribute* → Each graphic object is configured with zero or 66 more attributes. 67 68 * *object* → A reference to a prior graphic object. 69 70 * *place* → A specific point associated with an *object*. 71 72 * *position* → Any (2-D) point in space. An (x,y) pair. 73 74 * *expr* → A scalar expression. 75 76 77A complete input file to Pikchr consists of a single *statement-list*. 78 79## *statement-list*: [▶info](./stmtlist.md) 80 81 * *statement*? 82 * *statement-list* NEWLINE *statement*? 83 * *statement-list* **;** *statement*? 84 85## *statement*: [▶info](./stmt.md) 86 * *object-definition* 87 * LABEL **:** *object-definition* 88 * LABEL **:** *place* 89 * *direction* 90 * VARIABLE *assignment-op* *expr* 91 * **define** VARIABLE CODEBLOCK [▶info](./macro.md) 92 * **print** *print-argument* (**,** *print-argument*)\* 93 * **assert (** *expr* **==** *expr* **)** 94 * **assert (** *position* **==** *position* **)** 95 96 97## *direction*: 98 * **right** 99 * **down** 100 * **left** 101 * **up** 102 103## *assignment-op*: 104 * **=** 105 * **+=** 106 * **-=** 107 * **\*=** 108 * **/=** 109 110## *print-argument*: 111 * *expr* 112 * STRING 113 114## *object-definition*: 115 * *object-class* *attribute*\* 116 * STRING *text-attribute*\* *attribute*\* 117 * **[** *statement-list* **]** *attribute*\* 118 119## *object-class*: 120 * **arc** 121 * **arrow** 122 * **box** [▶info](./boxobj.md) 123 * **circle** [▶info](./circleobj.md) 124 * **cylinder** [▶info](./cylinderobj.md) 125 * **dot** 126 * **ellipse** [▶info](./ellipseobj.md) 127 * **file** [▶info](./fileobj.md) 128 * **line** 129 * **move** 130 * **oval** [▶info](./ovalobj.md) 131 * **spline** 132 * **text** 133 134## *attribute*: 135 * *path-attribute* [▶info](./pathattr.md) 136 * *location-attribute* [▶info](./locattr.md) 137 * STRING *text-attribute*\* [▶info](./annotate.md) 138 * **same** 139 * **same as** *object* 140 * *numeric-property* *new-property-value* 141 * **dashed** *expr*? 142 * **dotted** *expr*? 143 * **color** *color-expr* 144 * **fill** *color-expr* 145 * **behind** *object* [▶info](./behind.md) 146 * **cw** 147 * **ccw** 148 * **<-** [▶info](./arrowdir.md) 149 * **->** [▶info](./arrowdir.md) 150 * **<->** [▶info](./arrowdir.md) 151 * **invis**|**invisible** [▶info](./invis.md) 152 * **thick** [▶info](./thickthin.md) 153 * **thin** [▶info](./thickthin.md) 154 * **solid** [▶info](./thickthin.md) 155 * **chop** [▶info](./chop.md) 156 * **fit** [▶info](./fit.md) 157 158## *color-expr*: [▶info](./colorexpr.md) 159 * *expr* 160 161## *new-property-value*: [▶info](./newpropval.md) 162 * *expr* 163 * *expr* **%** 164 165## *numeric-property*: [▶info](./numprop.md) 166 * **diameter** 167 * **ht** 168 * **height** 169 * **rad** 170 * **radius** 171 * **thickness** 172 * **width** 173 * **wid** 174 175## *text-attribute*: [▶info](./textattr.md) 176 * **above** 177 * **aligned** 178 * **below** 179 * **big** 180 * **bold** 181 * **center** 182 * **italic** 183 * **ljust** 184 * **rjust** 185 * **small** 186 187## *path-attribute*: [▶info](./pathattr.md) 188 * **from** *position* 189 * **then**? **to** *position* 190 * **then**? **go**? *direction* *line-length*? 191 * **then**? **go**? *direction* **until**? **even with** *position* 192 * (**then**|**go**) *line-length*? **heading** *compass-angle* 193 * (**then**|**go**) *line-length*? *compass-direction* 194 * **close** 195 196## *line-length*: [▶info](./linelen.md) 197 198 * *expr* 199 * *expr* **%** 200 201## *compass-angle*: [▶info](./compassangle.md) 202 203 * *expr* 204 205## *compass-direction*: 206 * **n** 207 * **north** 208 * **ne** 209 * **e** 210 * **east** 211 * **se** 212 * **s** 213 * **south** 214 * **sw** 215 * **w** 216 * **west** 217 * **nw** 218 219## *location-attribute*: [▶info](./locattr.md) 220 * **at** *position* 221 * **with** *edgename* **at** *position* 222 * **with** *dot-edgename* **at** *position* 223 224## *position*: [▶info](./position.md) 225 226 * *expr* **,** *expr* 227 * *place* 228 * *place* **+** *expr* **,** *expr* 229 * *place* **-** *expr* **,** *expr* 230 * *place* **+ (** *expr* **,** *expr* **)** 231 * *place* **- (** *expr* **,** *expr* **)** 232 * **(** *position* **,** *position* **)** 233 * **(** *position* **)** 234 * *fraction* **of the way between** *position* **and** *position* 235 * *fraction* **way between** *position* **and** *position* 236 * *fraction* **between** *position* **and** *position* 237 * *fraction* **<** *position* **,** *position* **>** 238 * *distance* *which-way-from* *position* 239 240## *fraction*: 241 * *expr* 242 243## *distance* 244 * *expr* 245 246## *which-way-from*: 247 248 * **above** 249 * **below** 250 * **right of** 251 * **left of** 252 * **n of** 253 * **north of** 254 * **ne of** 255 * **e of** 256 * **east of** 257 * **se of** 258 * **s of** 259 * **south of** 260 * **sw of** 261 * **w of** 262 * **west of** 263 * **nw of** 264 * **heading** *compass-angle* **from** 265 266## *place*: [▶info](./place.md) 267 268 * *object* 269 * *object* *dot-edgename* 270 * *edgename* **of** *object* 271 * ORDINAL **vertex of** *object* 272 273## *object*: 274 * LABEL 275 * *object* **.** LABEL 276 * *nth-object* **of**|**in** *object* 277 278## *nth-object*: 279 280 * ORDINAL *object-class* 281 * ORDINAL **last** *object-class* 282 * ORDINAL **previous** *object-class* 283 * **last** *object-class* 284 * **previous** *object-class* 285 * **last** 286 * **previous** 287 * ORDINAL **[]** 288 * ORDINAL **last []** 289 * ORDINAL **previous []** 290 * **last []** 291 * **previous []** 292 293## *dot-edgename*: 294 * **.n** 295 * **.north** 296 * **.t** 297 * **.top** 298 * **.ne** 299 * **.e** 300 * **.east** 301 * **.right** 302 * **.se** 303 * **.s** 304 * **.south** 305 * **.bot** 306 * **.bottom** 307 * **.sw** 308 * **.w** 309 * **.west** 310 * **.left** 311 * **.nw** 312 * **.c** 313 * **.center** 314 * **.start** 315 * **.end** 316 317## *edgename*: 318 * **n** 319 * **north** 320 * **ne** 321 * **e** 322 * **east** 323 * **se** 324 * **s** 325 * **south** 326 * **sw** 327 * **w** 328 * **west** 329 * **nw** 330 * **t** 331 * **top** 332 * **bot** 333 * **bottom** 334 * **left** 335 * **right** 336 * **c** 337 * **center** 338 * **start** 339 * **end** 340 341 342## *expr*: 343 344 * NUMBER 345 * VARIABLE 346 * COLORNAME 347 * *place* **.x** 348 * *place* **.y** 349 * *object* *dot-property* 350 * **(** *expr* **)** 351 * *expr* **+** *expr* 352 * *expr* **-** *expr* 353 * *expr* **\*** *expr* 354 * *expr* **/** *expr* 355 * **-** *expr* 356 * **+** *expr* 357 * **abs (** *expr* **)** 358 * **cos (** *expr* **)** 359 * **dist (** *position* **,** *position* **)** 360 * **int (** *expr* **)** 361 * **max (** *expr* **,** *expr* **)** 362 * **min (** *expr* **,** *expr* **)** 363 * **sin (** *expr* **)** 364 * **sqrt (** *expr* **)** 365 366## *dot-property*: 367 368 * **.color** 369 * **.dashed** 370 * **.diameter** 371 * **.dotted** 372 * **.fill** 373 * **.ht** 374 * **.height** 375 * **.rad** 376 * **.radius** 377 * **.thickness** 378 * **.wid** 379 * **.width** 380