-
Notifications
You must be signed in to change notification settings - Fork 0
/
turtle_scanner.l
111 lines (106 loc) · 3.55 KB
/
turtle_scanner.l
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
%{
/* Copyright (c) 2008-2023 Alexey Ozeritskiy
* All rights reserved.
*/
#include <math.h>
#include "turtle.h"
%}
%option 8bit
%option noyywrap
%option prefix="turtle" case-insensitive
NUM [0-9]*\.?[0-9]+
INT [0-9]+
VAR [\.a-zA-Z]
%%
"f"|"d" { /*forward*/ return 'F'; }
"g"|"m" { /*skip*/ return 'G'; }
"!" { /*inverse*/ return '!'; }
"+" { /*inc angle*/ return '+'; }
"-" { /*dec angle*/ return '-'; }
"("{INT}")" { /*delay expand*/
sscanf(&yytext[1],"%d", &st->i);
st->str = yytext;
return DELAY;
}
"["|"]" { /*branch */ return yytext[0]; }
"C"{INT} { /*color*/
sscanf(&yytext[1],"%d", &st->i);
st->str = yytext;
return COLOR;
}
"<"{INT} { /*next color*/
sscanf(&yytext[1],"%d", &st->i);
st->str = yytext;
return INCCOLOR;
}
">"{INT} { /*prev color */
sscanf(&yytext[1],"%d", &st->i);
st->i = -st->i;
st->str = yytext;
return INCCOLOR;
}
"|" { /*inc 180 deg*/
st->i = 180;
st->str = yytext;
return INCNUMBER;
}
"\\"{INT} { /*inc INT deg */
sscanf(&yytext[1], "%d", &st->i);
st->str = yytext;
return INCNUMBER;
}
"/"{INT} { /*dec INT deg */
sscanf(&yytext[1], "%d", &st->i);
st->i = -st->i;
st->str = yytext;
return INCNUMBER;
}
"@"{NUM} { /*len multiply*/ sscanf(&yytext[1], "%lf", &st->m);
st->str = yytext; return NUMBER; }
"@Q"{NUM} { /*square root*/ sscanf(&yytext[2],"%lf", &st->m);
st->m = sqrt(st->m);
st->str = yytext;
BEGIN(INITIAL);
return NUMBER;
}
"@I"{NUM} { /*inverse*/ sscanf(&yytext[2],"%lf", &st->m);
st->m = 1.0 / st->m;
st->str = yytext;
BEGIN(INITIAL);
return NUMBER;
}
"@IQ"{NUM}|"@QI"{NUM} { /*inverse*/ sscanf(&yytext[3],"%lf", &st->m);
st->m = 1.0 / sqrt(st->m);
st->str = yytext;
BEGIN(INITIAL);
return NUMBER;
}
{VAR} { /*replace*/ return yytext[0]; }
.|"\n" {}
%%
/*
The standard drawing commands are:
F Draw forward
G Move forward (without drawing)
+ Increase angle
- Decrease angle
| Try to turn 180 degrees. (If angle is odd, the turn
will be the largest possible turn less than 180 degrees.)
These commands increment angle by the user specified angle value. They should be used when possible because they are fast. If greater flexibility is needed, use the following commands which keep a completely separate angle pointer which is specified in degrees.
D Draw forward
M Move forward
\nn Increase angle nn degrees
/nn Decrease angle nn degrees
Color control:
Cnn Select color nn
< nn Increment color by nn
> nn decrement color by nn
Advanced commands:
! Reverse directions (Switch meanings of +, - and , /)
@nnn Multiply line segment size by nnn
nnn may be a plain number, or may be preceded by
I for inverse, or Q for square root.
(e.g. @IQ2 divides size by the square root of 2)
[ Push. Stores current angle and position on a stack
] Pop. Return to location of last push
*/