mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Fixed problem with %recover
This commit is contained in:
parent
0d005fb3da
commit
8ad71c4adc
File diff suppressed because one or more lines are too long
BIN
docs/native.wasm
BIN
docs/native.wasm
Binary file not shown.
@ -144,7 +144,7 @@ int main(int argc, const char **argv) {
|
|||||||
name = peg::TraceOpeName::get(const_cast<peg::Ope &>(ope));
|
name = peg::TraceOpeName::get(const_cast<peg::Ope &>(ope));
|
||||||
|
|
||||||
auto lit = dynamic_cast<const peg::LiteralString *>(&ope);
|
auto lit = dynamic_cast<const peg::LiteralString *>(&ope);
|
||||||
if (lit) { name += " '" + lit->lit_ + "'"; }
|
if (lit) { name += " '" + peg::escape_characters(lit->lit_) + "'"; }
|
||||||
}
|
}
|
||||||
std::cout << "E " << pos << backtrack << "\t" << indent << "┌" << name
|
std::cout << "E " << pos << backtrack << "\t" << indent << "┌" << name
|
||||||
<< " #" << c.trace_ids.back() << std::endl;
|
<< " #" << c.trace_ids.back() << std::endl;
|
||||||
|
24
peglib.h
24
peglib.h
@ -201,6 +201,10 @@ inline std::string escape_characters(const char *s, size_t n) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string escape_characters(std::string_view sv) {
|
||||||
|
return escape_characters(sv.data(), sv.size());
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* resolve_escape_sequence
|
* resolve_escape_sequence
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
@ -685,11 +689,7 @@ private:
|
|||||||
if (len) {
|
if (len) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
int c = error_pos[i++];
|
int c = error_pos[i++];
|
||||||
if (std::ispunct(c)) {
|
if (!std::ispunct(c) && !std::isspace(c)) {
|
||||||
while (i < len && std::ispunct(error_pos[i])) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (i < len && !std::ispunct(error_pos[i]) &&
|
while (i < len && !std::ispunct(error_pos[i]) &&
|
||||||
!std::isspace(error_pos[i])) {
|
!std::isspace(error_pos[i])) {
|
||||||
i++;
|
i++;
|
||||||
@ -2121,7 +2121,6 @@ private:
|
|||||||
static const char *WHITESPACE_DEFINITION_NAME = "%whitespace";
|
static const char *WHITESPACE_DEFINITION_NAME = "%whitespace";
|
||||||
static const char *WORD_DEFINITION_NAME = "%word";
|
static const char *WORD_DEFINITION_NAME = "%word";
|
||||||
static const char *RECOVER_DEFINITION_NAME = "%recover";
|
static const char *RECOVER_DEFINITION_NAME = "%recover";
|
||||||
static const char *RECOVER_TO_DEFINITION_NAME = "%recover_to";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition
|
* Definition
|
||||||
@ -3213,8 +3212,6 @@ private:
|
|||||||
auto ope = ref(*data.grammar, ident, vs.sv().data(), is_macro, args);
|
auto ope = ref(*data.grammar, ident, vs.sv().data(), is_macro, args);
|
||||||
if (ident == RECOVER_DEFINITION_NAME) {
|
if (ident == RECOVER_DEFINITION_NAME) {
|
||||||
ope = rec(ope);
|
ope = rec(ope);
|
||||||
} else if (ident == RECOVER_TO_DEFINITION_NAME) {
|
|
||||||
ope = rec(ope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ignore) {
|
if (ignore) {
|
||||||
@ -3401,17 +3398,6 @@ private:
|
|||||||
rule.is_macro = true;
|
rule.is_macro = true;
|
||||||
rule.params = {"x"};
|
rule.params = {"x"};
|
||||||
}
|
}
|
||||||
|
|
||||||
// `%recover_to`
|
|
||||||
{
|
|
||||||
auto &rule = grammar[RECOVER_TO_DEFINITION_NAME];
|
|
||||||
rule <= oom(seq(npd(ref(grammar, "x", "", false, {})), dot()));
|
|
||||||
rule.name = RECOVER_TO_DEFINITION_NAME;
|
|
||||||
rule.s_ = "[native]";
|
|
||||||
rule.ignoreSemanticValue = true;
|
|
||||||
rule.is_macro = true;
|
|
||||||
rule.params = {"x"};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any dt = &data;
|
std::any dt = &data;
|
||||||
|
@ -1083,19 +1083,19 @@ TEST_CASE("Error recovery 1", "[error]") {
|
|||||||
|
|
||||||
HEADER <- '[' _ CATEGORY (':' _ ATTRIBUTES)? ']'
|
HEADER <- '[' _ CATEGORY (':' _ ATTRIBUTES)? ']'
|
||||||
|
|
||||||
CATEGORY <- < [-_a-zA-Z0-9 ]+ > _
|
CATEGORY <- < [-_a-zA-Z0-9\u0080-\uFFFF ]+ > _
|
||||||
ATTRIBUTES <- ATTRIBUTE (',' _ ATTRIBUTE)*
|
ATTRIBUTES <- ATTRIBUTE (',' _ ATTRIBUTE)*
|
||||||
ATTRIBUTE <- < [-_a-zA-Z0-9]+ > _
|
ATTRIBUTE <- < [-_a-zA-Z0-9\u0080-\uFFFF]+ > _
|
||||||
|
|
||||||
ENTRIES <- (ENTRY (__ ENTRY)*)?
|
ENTRIES <- (ENTRY (__ ENTRY)*)?
|
||||||
|
|
||||||
ENTRY <- ONE_WAY PHRASE ('|' _ PHRASE)*
|
ENTRY <- ONE_WAY PHRASE ('|' _ PHRASE)* !'='
|
||||||
/ PHRASE ('|' _ PHRASE)
|
/ PHRASE ('|' _ PHRASE)+ !'='
|
||||||
/ %recover_to(__ / HEADER)
|
/ %recover((!(__ / HEADER) .)+)
|
||||||
|
|
||||||
ONE_WAY <- PHRASE '=' _
|
ONE_WAY <- PHRASE '=' _
|
||||||
PHRASE <- WORD (' ' WORD)* _
|
PHRASE <- WORD (' ' WORD)* _
|
||||||
WORD <- < (![ \t\r\n=|[#] .)+ >
|
WORD <- < (![ \t\r\n=|[\]#] .)+ >
|
||||||
|
|
||||||
~__ <- _ (comment? nl _)+
|
~__ <- _ (comment? nl _)+
|
||||||
~_ <- [ \t]*
|
~_ <- [ \t]*
|
||||||
@ -1107,9 +1107,10 @@ TEST_CASE("Error recovery 1", "[error]") {
|
|||||||
REQUIRE(!!pg); // OK
|
REQUIRE(!!pg); // OK
|
||||||
|
|
||||||
std::vector<std::string> errors{
|
std::vector<std::string> errors{
|
||||||
R"(2:6: syntax error, unexpected '|', expecting <WORD>.)",
|
R"(3:6: syntax error, unexpected '|', expecting <WORD>.)",
|
||||||
R"(4:4: syntax error, unexpected '\n', expecting <WORD>.)",
|
R"(7:4: syntax error, unexpected '\n', expecting <WORD>.)",
|
||||||
R"(8:4: syntax error, unexpected '\n', expecting <WORD>.)"
|
R"(10:1: syntax error, unexpected '[', expecting <WORD>.)",
|
||||||
|
R"(18:17: syntax error, unexpected '=', expecting <ENTRY>, <WORD>.)",
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -1122,16 +1123,27 @@ TEST_CASE("Error recovery 1", "[error]") {
|
|||||||
pg.enable_ast();
|
pg.enable_ast();
|
||||||
|
|
||||||
std::shared_ptr<Ast> ast;
|
std::shared_ptr<Ast> ast;
|
||||||
REQUIRE_FALSE(pg.parse(R"([Section1]
|
REQUIRE_FALSE(pg.parse(R"([Section 1]
|
||||||
|
111 = 222 | 333
|
||||||
aaa || bbb
|
aaa || bbb
|
||||||
ccc = ddd
|
ccc = ddd
|
||||||
|
|
||||||
|
[Section 2]
|
||||||
eee
|
eee
|
||||||
|
fff | ggg
|
||||||
|
|
||||||
[Section2]
|
[Section 3
|
||||||
|
hhh | iii
|
||||||
|
|
||||||
fff
|
[Section 日本語]
|
||||||
|
ppp | qqq
|
||||||
|
|
||||||
ggg hhh | iii
|
[Section 4]
|
||||||
|
jjj | kkk
|
||||||
|
lll = mmm | nnn = ooo
|
||||||
|
|
||||||
|
[Section 5]
|
||||||
|
rrr | sss
|
||||||
|
|
||||||
)", ast));
|
)", ast));
|
||||||
|
|
||||||
@ -1140,30 +1152,54 @@ ggg hhh | iii
|
|||||||
REQUIRE(ast_to_s(ast) ==
|
REQUIRE(ast_to_s(ast) ==
|
||||||
R"(+ START
|
R"(+ START
|
||||||
+ SECTION
|
+ SECTION
|
||||||
- HEADER/0[CATEGORY] (Section1)
|
- HEADER/0[CATEGORY] (Section 1)
|
||||||
+ ENTRIES
|
+ ENTRIES
|
||||||
|
+ ENTRY/0
|
||||||
|
- ONE_WAY/0[WORD] (111)
|
||||||
|
- PHRASE/0[WORD] (222)
|
||||||
|
- PHRASE/0[WORD] (333)
|
||||||
+ ENTRY/2
|
+ ENTRY/2
|
||||||
+ ENTRY/0
|
+ ENTRY/0
|
||||||
- ONE_WAY/0[WORD] (ccc)
|
- ONE_WAY/0[WORD] (ccc)
|
||||||
- PHRASE/0[WORD] (ddd)
|
- PHRASE/0[WORD] (ddd)
|
||||||
+ ENTRY/2
|
|
||||||
+ SECTION
|
+ SECTION
|
||||||
- HEADER/0[CATEGORY] (Section2)
|
- HEADER/0[CATEGORY] (Section 2)
|
||||||
+ ENTRIES
|
+ ENTRIES
|
||||||
+ ENTRY/2
|
+ ENTRY/2
|
||||||
+ ENTRY/1
|
+ ENTRY/1
|
||||||
+ PHRASE
|
- PHRASE/0[WORD] (fff)
|
||||||
- WORD (ggg)
|
- PHRASE/0[WORD] (ggg)
|
||||||
- WORD (hhh)
|
+ ENTRY/2
|
||||||
|
+ ENTRY/1
|
||||||
|
- PHRASE/0[WORD] (hhh)
|
||||||
- PHRASE/0[WORD] (iii)
|
- PHRASE/0[WORD] (iii)
|
||||||
|
+ SECTION
|
||||||
|
- HEADER/0[CATEGORY] (Section 日本語)
|
||||||
|
+ ENTRIES
|
||||||
|
+ ENTRY/1
|
||||||
|
- PHRASE/0[WORD] (ppp)
|
||||||
|
- PHRASE/0[WORD] (qqq)
|
||||||
|
+ SECTION
|
||||||
|
- HEADER/0[CATEGORY] (Section 4)
|
||||||
|
+ ENTRIES
|
||||||
|
+ ENTRY/1
|
||||||
|
- PHRASE/0[WORD] (jjj)
|
||||||
|
- PHRASE/0[WORD] (kkk)
|
||||||
|
+ ENTRY/2
|
||||||
|
+ SECTION
|
||||||
|
- HEADER/0[CATEGORY] (Section 5)
|
||||||
|
+ ENTRIES
|
||||||
|
+ ENTRY/1
|
||||||
|
- PHRASE/0[WORD] (rrr)
|
||||||
|
- PHRASE/0[WORD] (sss)
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Error recovery 2", "[error]") {
|
TEST_CASE("Error recovery 2", "[error]") {
|
||||||
parser pg(R"(
|
parser pg(R"(
|
||||||
START <- ENTRY ((',' ENTRY) / %recover_to(',' / Space))* (_ / %recover_to('!.'))
|
START <- ENTRY ((',' ENTRY) / %recover((!(',' / Space) .)+))* (_ / %recover((!'!.' .)+))
|
||||||
ENTRY <- '[' ITEM (',' ITEM)* ']'
|
ENTRY <- '[' ITEM (',' ITEM)* ']'
|
||||||
ITEM <- WORD / NUM / %recover_to(',' / ']')
|
ITEM <- WORD / NUM / %recover((!(',' / ']') .)+)
|
||||||
NUM <- [0-9]+ ![a-z]
|
NUM <- [0-9]+ ![a-z]
|
||||||
WORD <- '"' [a-z]+ '"'
|
WORD <- '"' [a-z]+ '"'
|
||||||
|
|
||||||
@ -1174,14 +1210,14 @@ TEST_CASE("Error recovery 2", "[error]") {
|
|||||||
REQUIRE(!!pg); // OK
|
REQUIRE(!!pg); // OK
|
||||||
|
|
||||||
std::vector<std::string> errors{
|
std::vector<std::string> errors{
|
||||||
R"(1:6: syntax error, unexpected '],['.)",
|
R"(1:6: syntax error, unexpected ']'.)",
|
||||||
R"(1:18: syntax error, unexpected 'z', expecting <NUM>.)",
|
R"(1:18: syntax error, unexpected 'z', expecting <NUM>.)",
|
||||||
R"(1:24: syntax error, unexpected ',"', expecting <WORD>.)",
|
R"(1:24: syntax error, unexpected ',', expecting <WORD>.)",
|
||||||
R"(1:31: syntax error, unexpected 'ccc', expecting <NUM>.)",
|
R"(1:31: syntax error, unexpected 'ccc', expecting <NUM>.)",
|
||||||
R"(1:38: syntax error, unexpected 'ddd', expecting <NUM>.)",
|
R"(1:38: syntax error, unexpected 'ddd', expecting <NUM>.)",
|
||||||
R"(1:55: syntax error, unexpected '],[', expecting <WORD>.)",
|
R"(1:55: syntax error, unexpected ']', expecting <WORD>.)",
|
||||||
R"(1:58: syntax error, unexpected '\n', expecting <NUM>.)",
|
R"(1:58: syntax error, unexpected '\n', expecting <NUM>.)",
|
||||||
R"(1:56: syntax error, unexpected ',[', expecting <Space>.)",
|
R"(1:56: syntax error, unexpected ',', expecting <Space>.)",
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user