mirror of
				https://github.com/yhirose/cpp-peglib.git
				synced 2025-10-31 06:07:39 +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)); | ||||
| 
 | ||||
|             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 | ||||
|                     << " #" << 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; | ||||
| } | ||||
| 
 | ||||
| inline std::string escape_characters(std::string_view sv) { | ||||
|   return escape_characters(sv.data(), sv.size()); | ||||
| } | ||||
| 
 | ||||
| /*-----------------------------------------------------------------------------
 | ||||
|  *  resolve_escape_sequence | ||||
|  *---------------------------------------------------------------------------*/ | ||||
| @ -685,11 +689,7 @@ private: | ||||
|     if (len) { | ||||
|       size_t i = 0; | ||||
|       int c = error_pos[i++]; | ||||
|       if (std::ispunct(c)) { | ||||
|         while (i < len && std::ispunct(error_pos[i])) { | ||||
|           i++; | ||||
|         } | ||||
|       } else { | ||||
|       if (!std::ispunct(c) && !std::isspace(c)) { | ||||
|         while (i < len && !std::ispunct(error_pos[i]) && | ||||
|                !std::isspace(error_pos[i])) { | ||||
|           i++; | ||||
| @ -2121,7 +2121,6 @@ private: | ||||
| static const char *WHITESPACE_DEFINITION_NAME = "%whitespace"; | ||||
| static const char *WORD_DEFINITION_NAME = "%word"; | ||||
| static const char *RECOVER_DEFINITION_NAME = "%recover"; | ||||
| static const char *RECOVER_TO_DEFINITION_NAME = "%recover_to"; | ||||
| 
 | ||||
| /*
 | ||||
|  * Definition | ||||
| @ -3213,8 +3212,6 @@ private: | ||||
|         auto ope = ref(*data.grammar, ident, vs.sv().data(), is_macro, args); | ||||
|         if (ident == RECOVER_DEFINITION_NAME) { | ||||
|           ope = rec(ope); | ||||
|         } else if (ident == RECOVER_TO_DEFINITION_NAME) { | ||||
|           ope = rec(ope); | ||||
|         } | ||||
| 
 | ||||
|         if (ignore) { | ||||
| @ -3401,17 +3398,6 @@ private: | ||||
|         rule.is_macro = true; | ||||
|         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; | ||||
|  | ||||
| @ -1083,19 +1083,19 @@ TEST_CASE("Error recovery 1", "[error]") { | ||||
| 
 | ||||
|     HEADER     <- '[' _ CATEGORY (':' _  ATTRIBUTES)? ']' | ||||
| 
 | ||||
|     CATEGORY   <- < [-_a-zA-Z0-9 ]+ > _ | ||||
|     CATEGORY   <- < [-_a-zA-Z0-9\u0080-\uFFFF ]+ > _ | ||||
|     ATTRIBUTES <- ATTRIBUTE (',' _ ATTRIBUTE)* | ||||
|     ATTRIBUTE  <- < [-_a-zA-Z0-9]+ > _ | ||||
|     ATTRIBUTE  <- < [-_a-zA-Z0-9\u0080-\uFFFF]+ > _ | ||||
| 
 | ||||
|     ENTRIES    <- (ENTRY (__ ENTRY)*)? | ||||
| 
 | ||||
|     ENTRY      <- ONE_WAY PHRASE ('|' _ PHRASE)* | ||||
|                 / PHRASE ('|' _ PHRASE) | ||||
|                 / %recover_to(__ / HEADER) | ||||
|     ENTRY      <- ONE_WAY PHRASE ('|' _ PHRASE)* !'=' | ||||
|                 / PHRASE ('|' _ PHRASE)+ !'=' | ||||
|                 / %recover((!(__ / HEADER) .)+) | ||||
| 
 | ||||
|     ONE_WAY    <- PHRASE '=' _ | ||||
|     PHRASE     <- WORD (' ' WORD)* _ | ||||
|     WORD       <- < (![ \t\r\n=|[#] .)+ > | ||||
|     WORD       <- < (![ \t\r\n=|[\]#] .)+ > | ||||
| 
 | ||||
|     ~__        <- _ (comment? nl _)+ | ||||
|     ~_         <- [ \t]* | ||||
| @ -1107,9 +1107,10 @@ TEST_CASE("Error recovery 1", "[error]") { | ||||
|   REQUIRE(!!pg); // OK
 | ||||
| 
 | ||||
|   std::vector<std::string> errors{ | ||||
|     R"(2:6: syntax error, unexpected '|', expecting <WORD>.)", | ||||
|     R"(4:4: syntax error, unexpected '\n', expecting <WORD>.)", | ||||
|     R"(8:4: syntax error, unexpected '\n', expecting <WORD>.)" | ||||
|     R"(3:6: syntax error, unexpected '|', expecting <WORD>.)", | ||||
|     R"(7: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; | ||||
| @ -1123,15 +1124,26 @@ TEST_CASE("Error recovery 1", "[error]") { | ||||
| 
 | ||||
|   std::shared_ptr<Ast> ast; | ||||
|   REQUIRE_FALSE(pg.parse(R"([Section 1] | ||||
| 111 = 222 | 333 | ||||
| aaa || bbb | ||||
| ccc = ddd | ||||
| eee | ||||
| 
 | ||||
| [Section 2] | ||||
| eee | ||||
| fff | ggg | ||||
| 
 | ||||
| fff | ||||
| [Section 3 | ||||
| hhh | iii | ||||
| 
 | ||||
| ggg hhh | iii | ||||
| [Section 日本語] | ||||
| ppp | qqq | ||||
| 
 | ||||
| [Section 4] | ||||
| jjj | kkk | ||||
| lll = mmm | nnn = ooo | ||||
| 
 | ||||
| [Section 5] | ||||
| rrr | sss | ||||
| 
 | ||||
|   )", ast)); | ||||
| 
 | ||||
| @ -1142,28 +1154,52 @@ R"(+ START | ||||
|   + SECTION | ||||
|     - HEADER/0[CATEGORY] (Section 1) | ||||
|     + ENTRIES | ||||
|       + ENTRY/0 | ||||
|         - ONE_WAY/0[WORD] (111) | ||||
|         - PHRASE/0[WORD] (222) | ||||
|         - PHRASE/0[WORD] (333) | ||||
|       + ENTRY/2 | ||||
|       + ENTRY/0 | ||||
|         - ONE_WAY/0[WORD] (ccc) | ||||
|         - PHRASE/0[WORD] (ddd) | ||||
|       + ENTRY/2 | ||||
|   + SECTION | ||||
|     - HEADER/0[CATEGORY] (Section 2) | ||||
|     + ENTRIES | ||||
|       + ENTRY/2 | ||||
|       + ENTRY/1 | ||||
|         + PHRASE | ||||
|           - WORD (ggg) | ||||
|           - WORD (hhh) | ||||
|         - PHRASE/0[WORD] (fff) | ||||
|         - PHRASE/0[WORD] (ggg) | ||||
|       + ENTRY/2 | ||||
|       + ENTRY/1 | ||||
|         - PHRASE/0[WORD] (hhh) | ||||
|         - 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]") { | ||||
|   parser pg(R"( | ||||
|     START <- ENTRY ((',' ENTRY) / %recover_to(',' / Space))* (_ / %recover_to('!.')) | ||||
|     START <- ENTRY ((',' ENTRY) / %recover((!(',' / Space) .)+))* (_ / %recover((!'!.' .)+)) | ||||
|     ENTRY <- '[' ITEM (',' ITEM)* ']' | ||||
|     ITEM  <- WORD / NUM / %recover_to(',' / ']') | ||||
|     ITEM  <- WORD / NUM / %recover((!(',' / ']') .)+) | ||||
|     NUM   <- [0-9]+ ![a-z] | ||||
|     WORD  <- '"' [a-z]+ '"' | ||||
| 
 | ||||
| @ -1174,14 +1210,14 @@ TEST_CASE("Error recovery 2", "[error]") { | ||||
|   REQUIRE(!!pg); // OK
 | ||||
| 
 | ||||
|   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: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: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:56: syntax error, unexpected ',[', expecting <Space>.)", | ||||
|     R"(1:56: syntax error, unexpected ',', expecting <Space>.)", | ||||
|   }; | ||||
| 
 | ||||
|   size_t i = 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user