-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsymbols.c
141 lines (123 loc) · 2.97 KB
/
symbols.c
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "symbols.h"
/* because '!' = 33 */
#define MAX_RULES 32
void init_rule_set(struct rule_set *rules)
{
if(rules->num_rules == 0)
rules->rules = NULL;
else
rules->rules = malloc(rules->rule_size * rules->num_rules);
}
void free_rule_set(struct rule_set *rules)
{
if(rules->rules)
free(rules->rules);
rules->rules = NULL;
}
char* get_rule(int rule_no, struct rule_set *rules)
{
if(rule_no > rules->num_rules) return NULL;
return rules->rules + rule_no * rules->rule_size;
}
void print_syms(char *syms, int syms_size, int max_num)
{
int i;
for(i=0; i < syms_size; ++i) {
/* printf(" %i:", i); */
if(syms[i] <= max_num)
printf("%i", syms[i]);
else
printf("%c", syms[i]);
}
printf("\n");
}
void print_rule_set(struct rule_set *rules)
{
int i;
for(i=0; i < rules->num_rules; ++i)
print_syms(get_rule(i, rules), rules->rule_size, rules->num_rules);
}
void chars_to_rule(char *chars, int length, int max_rule)
{
int i;
char val;
for(i=0; i < length; ++i) {
val = chars[i] - '0';
if(max_rule > val && val >= 0)
chars[i] = val;
}
}
int expansion_length(char *exp, int exp_size, struct rule_set *rule)
{
int i;
int total = 0;
for(i=0; i < exp_size; ++i)
if(exp[i] <= rule->num_rules)
total += rule->rule_size;
else
total++;
/*
printf("expansion_length: %i\n", total);
*/
return total;
}
void expand_rule(char exp[MAX_EXPANSION_SIZE],
int *exp_size, struct rule_set *rules)
{
static char new_exp[MAX_EXPANSION_SIZE];
char *rule = NULL;
int i;
int exp_pos = 0;
int rule_pos = 0;
int rule_len;
for(i=0; i < *exp_size; ++i) {
if(exp_pos >= MAX_EXPANSION_SIZE) break;
if(exp[i] > rules->num_rules)
new_exp[exp_pos++] = exp[i]; /* Not a rule, just a char */
else {
rule = get_rule(exp[i], rules);
rule_len = rules->rule_size;
rule_pos = 0;
rule_len--;
/* copy chars */
while(rule_pos <= rule_len && exp_pos < MAX_EXPANSION_SIZE)
new_exp[exp_pos++] = rule[rule_pos++];
}
}
/*
printf("Expand: %i -> %i\n", *exp_size, exp_pos);
*/
*exp_size = exp_pos;
memcpy(exp, new_exp, exp_pos);
}
void random_rule_set(struct rule_set *rules)
{
int i;
char rand_char;
char special_chars[5] = "+-()!";
for(i=0; i < rules->rule_size * rules->num_rules; ++i) {
/* special chars +-()! */
rand_char = (int)((5 + rules->num_rules) * (rand() / (float)RAND_MAX));
/*printf("%i: %i", i, rand_char); */
if(rand_char >= rules->num_rules)
rules->rules[i] = special_chars[rand_char - rules->num_rules];
else
rules->rules[i] = rand_char;
/* if(rand_char >= rules->num_rules)
printf("=%c\n", rules->rules[i]);
else
printf("=%i\n", rules->rules[i]);
*/
}
/*
print_rule_set(rules);
*/
}
int is_terminal(char exp[MAX_EXPANSION_SIZE], int exp_size, int nrules)
{
int i;
for(i = 0; i < exp_size; ++i)
if(exp[i] < nrules)
return 0;
return 1;
}