Commit 89eace0d authored by Daniel Salzman's avatar Daniel Salzman

yparser: remove relaxed formatting rules

parent cd2fa254
......@@ -46,6 +46,10 @@ typedef struct {
int cs;
/*! Indication if the current item was already processed. */
bool processed;
/*! Current block indentation. */
size_t indent;
/*! Last id dash position. */
size_t id_pos;
/*! Input parameters. */
struct {
......
......@@ -28,126 +28,110 @@
static const char _yparser_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 6, 1, 7, 1,
8, 1, 9, 1, 10, 2, 1, 0,
2, 2, 3, 2, 4, 0, 2, 5,
6, 3, 1, 5, 6
8, 1, 9, 1, 10, 1, 13, 2,
1, 0, 2, 2, 3, 2, 4, 0,
2, 5, 6, 2, 10, 11, 2, 12,
10, 3, 1, 5, 6, 3, 1, 10,
11, 3, 1, 12, 10
};
static const unsigned char _yparser_key_offsets[] = {
0, 0, 12, 13, 22, 33, 37, 49,
62, 67, 72, 77, 88, 92, 105, 117,
129, 134, 140, 152, 164, 174, 185, 190,
195, 206, 218
0, 0, 10, 11, 12, 19, 28, 30,
31, 41, 51, 54, 57, 59, 68, 70,
71, 81, 91, 99, 102, 104, 107, 110,
119, 121, 123, 134, 144
};
static const char _yparser_trans_keys[] = {
9, 10, 13, 32, 35, 45, 48, 57,
65, 90, 97, 122, 10, 9, 13, 32,
48, 57, 65, 90, 97, 122, 9, 13,
32, 45, 58, 48, 57, 65, 90, 97,
122, 9, 13, 32, 58, 9, 13, 32,
10, 32, 35, 45, 48, 57, 65, 90,
97, 122, 10, 32, 32, 48, 57, 65,
90, 97, 122, 32, 45, 58, 48, 57,
65, 90, 97, 122, 32, 58, 32, 32,
33, 34, 92, 36, 43, 45, 90, 94,
126, 9, 10, 13, 32, 33, 35, 92,
36, 43, 45, 90, 94, 126, 9, 10,
13, 32, 35, 9, 13, 34, 32, 126,
9, 10, 13, 32, 35, 9, 13, 32,
45, 58, 48, 57, 65, 90, 97, 122,
9, 13, 32, 58, 9, 10, 13, 32,
34, 35, 91, 33, 43, 45, 92, 94,
126, 9, 10, 13, 32, 33, 35, 44,
92, 36, 90, 94, 126, 9, 10, 13,
32, 34, 35, 44, 92, 33, 90, 94,
126, 9, 13, 34, 32, 126, 9, 10,
13, 32, 35, 44, 9, 13, 32, 33,
34, 92, 36, 43, 45, 90, 94, 126,
9, 13, 32, 33, 34, 92, 36, 43,
45, 90, 94, 126, 9, 13, 32, 33,
44, 93, 36, 90, 92, 126, 9, 13,
32, 33, 34, 44, 93, 36, 90, 92,
126, 9, 13, 34, 32, 126, 9, 13,
32, 44, 93, 9, 13, 32, 45, 58,
48, 57, 65, 90, 97, 122, 9, 10,
13, 32, 35, 45, 48, 57, 65, 90,
97, 122, 9, 10, 13, 32, 35, 45,
48, 57, 65, 90, 97, 122, 0
126, 10, 32, 33, 92, 36, 43, 45,
90, 94, 126, 10, 32, 35, 34, 32,
126, 10, 32, 32, 45, 58, 48, 57,
65, 90, 97, 122, 32, 58, 32, 32,
33, 34, 91, 36, 43, 45, 92, 94,
126, 32, 33, 34, 92, 36, 43, 45,
90, 94, 126, 32, 33, 44, 93, 36,
90, 92, 126, 32, 44, 93, 10, 32,
34, 32, 126, 32, 44, 93, 32, 45,
58, 48, 57, 65, 90, 97, 122, 32,
58, 10, 32, 10, 32, 34, 35, 91,
33, 43, 45, 92, 94, 126, 10, 32,
35, 45, 48, 57, 65, 90, 97, 122,
10, 32, 35, 45, 48, 57, 65, 90,
97, 122, 0
};
static const char _yparser_single_lengths[] = {
0, 6, 1, 3, 5, 4, 6, 7,
5, 3, 5, 5, 4, 7, 8, 8,
3, 6, 6, 6, 6, 7, 3, 5,
5, 6, 6
0, 4, 1, 1, 1, 3, 2, 1,
4, 4, 3, 1, 2, 3, 2, 1,
4, 4, 4, 3, 2, 1, 3, 3,
2, 2, 5, 4, 4
};
static const char _yparser_range_lengths[] = {
0, 3, 0, 3, 3, 0, 3, 3,
0, 1, 0, 3, 0, 3, 2, 2,
1, 0, 3, 3, 2, 2, 1, 0,
3, 3, 3
0, 3, 0, 0, 3, 3, 0, 0,
3, 3, 0, 1, 0, 3, 0, 0,
3, 3, 2, 0, 0, 1, 0, 3,
0, 0, 3, 3, 3
};
static const unsigned char _yparser_index_offsets[] = {
0, 0, 10, 12, 19, 28, 33, 43,
54, 60, 65, 71, 80, 85, 96, 107,
118, 123, 130, 140, 150, 159, 169, 174,
180, 189, 199
0, 0, 8, 10, 12, 17, 24, 27,
29, 37, 45, 49, 52, 55, 62, 65,
67, 75, 83, 90, 94, 97, 100, 104,
111, 114, 117, 126, 134
};
static const char _yparser_indicies[] = {
1, 2, 1, 1, 3, 4, 5, 5,
5, 0, 2, 3, 4, 4, 4, 6,
6, 6, 0, 7, 7, 7, 8, 9,
8, 8, 8, 0, 10, 10, 10, 11,
0, 11, 11, 11, 12, 13, 12, 12,
12, 12, 0, 14, 15, 14, 14, 16,
17, 16, 16, 16, 16, 0, 18, 2,
18, 18, 3, 0, 19, 19, 20, 19,
0, 14, 15, 14, 14, 17, 0, 21,
21, 21, 22, 23, 22, 22, 22, 0,
24, 24, 24, 25, 0, 25, 2, 25,
25, 27, 3, 28, 26, 26, 26, 0,
29, 15, 29, 29, 30, 17, 31, 30,
30, 30, 0, 32, 2, 32, 32, 27,
3, 33, 26, 26, 26, 0, 34, 34,
35, 34, 0, 29, 15, 29, 29, 17,
31, 0, 33, 33, 33, 26, 27, 26,
26, 26, 26, 0, 28, 28, 28, 36,
37, 36, 36, 36, 36, 0, 38, 38,
38, 39, 40, 14, 39, 39, 0, 41,
41, 41, 36, 37, 28, 18, 36, 36,
0, 42, 42, 43, 42, 0, 38, 38,
38, 40, 14, 0, 44, 44, 44, 45,
46, 45, 45, 45, 0, 1, 2, 1,
1, 3, 4, 47, 47, 47, 0, 48,
49, 48, 48, 50, 51, 52, 52, 52,
0, 0
1, 2, 3, 4, 5, 5, 5, 0,
1, 3, 6, 0, 6, 7, 7, 7,
0, 8, 9, 10, 9, 9, 9, 0,
11, 12, 0, 13, 0, 13, 14, 15,
14, 14, 14, 14, 0, 16, 17, 18,
18, 18, 18, 18, 0, 1, 19, 3,
0, 21, 20, 0, 16, 17, 0, 22,
23, 24, 23, 23, 23, 0, 25, 26,
0, 27, 0, 27, 14, 15, 28, 14,
14, 14, 0, 28, 29, 30, 29, 29,
29, 29, 0, 31, 32, 33, 34, 32,
32, 0, 35, 28, 36, 0, 1, 19,
0, 38, 37, 0, 31, 33, 34, 0,
39, 40, 41, 40, 40, 40, 0, 42,
43, 0, 1, 44, 0, 1, 44, 15,
3, 28, 14, 14, 14, 0, 1, 2,
3, 4, 45, 45, 45, 0, 46, 47,
48, 49, 50, 50, 50, 0, 0
};
static const char _yparser_trans_targs[] = {
0, 1, 26, 2, 3, 24, 4, 5,
4, 6, 5, 6, 7, 9, 8, 26,
7, 2, 8, 9, 10, 12, 11, 13,
12, 13, 14, 16, 19, 15, 14, 18,
15, 18, 16, 17, 20, 22, 21, 20,
19, 21, 22, 23, 12, 24, 13, 11,
1, 26, 2, 3, 11
0, 28, 1, 2, 3, 13, 4, 5,
6, 5, 7, 6, 7, 8, 9, 11,
28, 10, 9, 10, 11, 12, 14, 13,
15, 14, 15, 16, 17, 18, 21, 19,
18, 17, 20, 19, 20, 21, 22, 24,
23, 25, 24, 25, 26, 23, 28, 1,
2, 3, 23
};
static const char _yparser_trans_actions[] = {
19, 0, 1, 0, 0, 30, 30, 17,
11, 17, 0, 0, 24, 5, 9, 27,
7, 9, 0, 7, 0, 13, 11, 13,
0, 0, 24, 5, 0, 9, 7, 9,
0, 0, 7, 0, 24, 5, 9, 7,
9, 0, 7, 0, 15, 11, 15, 30,
3, 21, 3, 3, 33
21, 1, 35, 0, 38, 32, 19, 32,
17, 11, 17, 0, 0, 0, 26, 5,
29, 9, 7, 0, 7, 0, 15, 11,
15, 0, 0, 0, 0, 26, 5, 9,
7, 9, 9, 0, 0, 7, 0, 13,
11, 13, 0, 0, 0, 32, 23, 45,
3, 49, 41
};
static const char _yparser_eof_actions[] = {
0, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 0, 3
0, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 0, 3
};
......@@ -155,7 +139,7 @@ static const char _yparser_eof_actions[] = {
int _yp_start_state =
25
27
;
int _yp_parse(
......@@ -164,6 +148,10 @@ int _yp_parse(
// Parser input limits (Ragel internals).
const char *p, *pe, *eof;
// Current item indent.
size_t indent = 0;
// Current id dash position.
size_t id_pos = 0;
// Indicates if the current parsing step contains an item.
bool found = false;
......@@ -293,6 +281,10 @@ _match:
break;
case 5:
{
if (indent > 0 && parser->indent > 0 &&
indent != parser->indent) {
return KNOT_EPARSEFAIL;
}
parser->processed = false;
parser->key_len = 0;
parser->data_len = 0;
......@@ -310,22 +302,45 @@ _match:
case 7:
{
parser->key[parser->key_len] = '\0';
parser->indent = 0;
parser->event = YP_EKEY0;
}
break;
case 8:
{
parser->key[parser->key_len] = '\0';
parser->indent = indent;
parser->event = YP_EKEY1;
}
break;
case 9:
{
parser->key[parser->key_len] = '\0';
parser->indent = indent;
parser->id_pos = id_pos;
parser->event = YP_EID;
}
break;
case 10:
{
indent++;
}
break;
case 11:
{
id_pos++;
}
break;
case 12:
{
if (id_pos > 0 && parser->id_pos > 0 &&
id_pos != parser->id_pos) {
return KNOT_EPARSEFAIL;
}
parser->indent = 0;
}
break;
case 13:
{
return KNOT_EPARSEFAIL;
}
......@@ -352,7 +367,7 @@ _again:
parser->processed = false;
}
break;
case 10:
case 13:
{
return KNOT_EPARSEFAIL;
}
......
......@@ -45,10 +45,11 @@
comment = comment_char . (^newline_char)*;
# White space processing.
sep_char = [ \t\r];
sep_char = ' ';
sep = sep_char+;
blank = (sep? :> comment?). newline_char;
rest = ((sep :> comment) | sep?). newline_char;
# Data processing.
action _item_data_init {
......@@ -78,15 +79,15 @@
) $_item_data;
data_str = (quote_char . data_str_char* . quote_char);
item_data = (data_char+ | data_str) >_item_data_init %_item_data_exit;
item_data_plus =
item_data .
((sep | ',' | (sep . ',' . sep) | (sep . ',') | (',' . sep)) .
item_data)*;
item_data_list =
('\[' . sep? . item_data_plus . sep? . '\]') | item_data_plus;
item_data_plus = item_data . ((sep? . ',' . sep?) . item_data)*;
item_data_list = '\[' . sep? . item_data_plus . sep? . '\]';
# Key processing.
action _key_init {
if (indent > 0 && parser->indent > 0 &&
indent != parser->indent) {
return KNOT_EPARSEFAIL;
}
parser->processed = false;
parser->key_len = 0;
parser->data_len = 0;
......@@ -100,25 +101,41 @@
}
action _key0_exit {
parser->key[parser->key_len] = '\0';
parser->indent = 0;
parser->event = YP_EKEY0;
}
action _key1_exit {
parser->key[parser->key_len] = '\0';
parser->indent = indent;
parser->event = YP_EKEY1;
}
action _id_exit {
parser->key[parser->key_len] = '\0';
parser->indent = indent;
parser->id_pos = id_pos;
parser->event = YP_EID;
}
key_data_sep = sep? . ":" . sep?;
key_name = alnum . ("-" | alnum)*;
key0 = key_name >_key_init $_key %_key0_exit;
key1 = sep . key_name >_key_init $_key %_key1_exit;
id = sep? . "-" . sep? . key_name >_key_init $_key %_id_exit;
item = (((key0 . key_data_sep . item_data_list?)
|(key1 . key_data_sep . item_data_list?)
|(id . key_data_sep . item_data )
) . blank
action _indent {
indent++;
}
action _id {
id_pos++;
}
action _dash_init {
if (id_pos > 0 && parser->id_pos > 0 &&
id_pos != parser->id_pos) {
return KNOT_EPARSEFAIL;
}
parser->indent = 0;
}
key_name = (alnum . ("-" | alnum)*) >_key_init $_key;
key0 = key_name %_key0_exit;
key1 = sep $_indent . key_name %_key1_exit;
id = ((sep $_id)? . "-" >_dash_init . sep) $_indent . key_name %_id_exit;
item = (((key0 . sep? . ":" . (sep . (item_data_list | item_data))?)
|(key1 . sep? . ":" . sep . (item_data_list | item_data))
|(id . sep? . ":" . sep . item_data)
) . rest
);
# Main processing loop.
......@@ -140,6 +157,10 @@ int _yp_parse(
// Parser input limits (Ragel internals).
const char *p, *pe, *eof;
// Current item indent.
size_t indent = 0;
// Current id dash position.
size_t id_pos = 0;
// Indicates if the current parsing step contains an item.
bool found = false;
......
......@@ -22,53 +22,56 @@
#include "libknot/internal/yparser/yparser.h"
#include "libknot/errcode.h"
const char *syntax =
const char *syntax_ok =
"a:\n"
"a :\n"
"a : #comment\n"
"\n"
"b:\"b\"\n"
"b: \"b\"\n"
"b:b#comment\n"
"b: b #comment\n"
"b :b\n"
"b : b\n"
"b: [b]#comment\n"
"b: [ b] # comment\n"
"b: [b ]\n"
"b: [ b ]\n"
"\n"
" f:\"f\"\n"
" f: \"f\"\n"
" f:f#comment\n"
" f: f #comment\n"
" f :f\n"
" f : f\n"
" f: [f]#comment\n"
" f: [ f] # comment\n"
" f: [f ]\n"
" f: [ f ]\n"
"\n"
"c: a b\n"
"c: a,b\n"
"c: a, b\n"
"c: a ,b\n"
"c: a , b\n"
"c: [a b]\n"
"c: [a,b]\n"
"c: [a, b]\n"
"c: [a ,b]\n"
"c: [a , b]\n"
"c: [ a , b ]\n"
"\n"
"-d:d\n"
" -d:d\n"
" - d:d\n"
" - d: d\n"
" - d :d\n"
" - d : d\n"
"- d: d\n"
"- d : d # comment\n"
"\n"
"e: \"a#b' c[d,]\"";
"e: \"a#b' c[d,]\"\n"
"\n"
"zone:\n"
" - domain: example.\n"
" master: bind\n"
" - domain: example.\n"
" master: bind\n";
const char *syntax_error1 =
"f:\n"
" - a: b\n"
" - b: c\n";
const char *syntax_error2 =
"f:\n"
" - a: b\n"
" c: d\n";
const char *syntax_error3 =
"f:\n"
" a: b\n"
" c: d\n";
int main(int argc, char *argv[])
{
......@@ -81,7 +84,8 @@ int main(int argc, char *argv[])
yp_parser_t *yp = &yparser;
yp_init(yp);
ret = yp_set_input_string(yp, syntax, strlen(syntax));
// OK input.
ret = yp_set_input_string(yp, syntax_ok, strlen(syntax_ok));
ok(ret == KNOT_EOK, "set input string");
line = 1;
......@@ -94,7 +98,7 @@ int main(int argc, char *argv[])
}
line = 5;
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 6; i++) {
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. key0 with value", i);
ok(yp->key_len == 1 && yp->key[0] == 'b' &&
......@@ -103,8 +107,8 @@ int main(int argc, char *argv[])
"compare %i. key0 with value", i);
}
line = 16;
for (int i = 0; i < 10; i++) {
line = 12;
for (int i = 0; i < 6; i++) {
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. key1 with value", i);
ok(yp->key_len == 1 && yp->key[0] == 'f' &&
......@@ -113,8 +117,8 @@ int main(int argc, char *argv[])
"compare %i. key1 with value", i);
}
line = 27;
for (int i = 0; i < 11; i++) {
line = 19;
for (int i = 0; i < 5; i++) {
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. key0 with first value", i);
ok(yp->key_len == 1 && yp->key[0] == 'c' &&
......@@ -130,8 +134,8 @@ int main(int argc, char *argv[])
"compare %i. key0 with second value", i);
}
line = 39;
for (int i = 0; i < 6; i++) {
line = 25;
for (int i = 0; i < 2; i++) {
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. id", i);
ok(yp->key_len == 1 && yp->key[0] == 'd' &&
......@@ -140,7 +144,7 @@ int main(int argc, char *argv[])
"compare %i. id", i);
}
line = 46;
line = 28;
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key0 with quoted value");
ok(yp->key_len == 1 && yp->key[0] == 'e' && yp->data_len == 10 &&
......@@ -148,9 +152,63 @@ int main(int argc, char *argv[])
yp->event == YP_EKEY0 && yp->line_count == line,
"compare key0 with quoted value");
line = 30;
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key0");
ok(yp->key_len == 4 && strcmp(yp->key, "zone") == 0 &&
yp->data_len == 0 &&
yp->event == YP_EKEY0 && yp->line_count == line,
"compare key0 value");
line = 31;
for (int i = 0; i < 2; i++) {
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. id", i);
ok(yp->key_len == 6 && strcmp(yp->key, "domain") == 0 &&
yp->data_len == 8 && strcmp(yp->data, "example.") == 0 &&
yp->event == YP_EID && yp->line_count == line + 2 * i,
"compare id");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse %i. key1", i);
ok(yp->key_len == 6 && strcmp(yp->key, "master") == 0 &&
yp->data_len == 4 && strcmp(yp->data, "bind") == 0 &&
yp->event == YP_EKEY1 && yp->line_count == line + 2 * i + 1,
"compare key1");
}
ret = yp_parse(yp);
ok(ret == KNOT_EOF, "parse EOF");
// Error input 1.
ret = yp_set_input_string(yp, syntax_error1, strlen(syntax_error1));
ok(ret == KNOT_EOK, "set error input string 1");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key0");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key1");
ret = yp_parse(yp);
ok(ret == KNOT_EPARSEFAIL, "parse invalid key1");
// Error input 2.
ret = yp_set_input_string(yp, syntax_error2, strlen(syntax_error2));
ok(ret == KNOT_EOK, "set error input string 2");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key0");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key1");
ret = yp_parse(yp);
ok(ret == KNOT_EPARSEFAIL, "parse invalid key1");
// Error input 3.
ret = yp_set_input_string(yp, syntax_error3, strlen(syntax_error3));
ok(ret == KNOT_EOK, "set error input string 3");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key0");
ret = yp_parse(yp);
ok(ret == KNOT_EOK, "parse key1");
ret = yp_parse(yp);
ok(ret == KNOT_EPARSEFAIL, "parse invalid key1");
yp_deinit(yp);
return 0;
......
......@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
ok(yp_opt(ctx->data) == 1, "value check");
/* Group test. */
str = "group:\n integer: 20\n string: short, \"long string\"";
str = "group:\n integer: 20\n string: [short, \"long string\"]";
ret = yp_set_input_string(yp, str, strlen(str));
ok(ret == KNOT_EOK, "set input string");
ret = yp_parse(yp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment