From d705daba81e8528d1809b54c8107cfbcaf3c71f2 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 4 Aug 2017 11:07:45 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Reduce=20backtracking=20in=20Lua=20?= =?UTF-8?q?=E2=80=9Cfor=E2=80=9D=20statement=20parsing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When parsing “for a in …” the parser will currently first try to match a rule of the form “for a = …” and then backtrack, causing the name “a” to be parsed twice. This refactoring delays the choice and avoids backtracking. This partly addresses the discussion in #32. --- src/example/pegtl/lua53_parse.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/example/pegtl/lua53_parse.cpp b/src/example/pegtl/lua53_parse.cpp index ce7c2813d..5dc39a111 100644 --- a/src/example/pegtl/lua53_parse.cpp +++ b/src/example/pegtl/lua53_parse.cpp @@ -300,9 +300,9 @@ namespace lua53 struct else_statement : pegtl::if_must< key_else, statement_list< key_end > > {}; struct if_statement : pegtl::if_must< key_if, seps, expression, seps, key_then, statement_list< at_elseif_else_end >, seps, pegtl::until< pegtl::sor< else_statement, key_end >, elseif_statement, seps > > {}; - struct for_statement_one : pegtl::seq< name, seps, pegtl::one< '=' >, seps, expression, seps, pegtl::one< ',' >, seps, expression, pegtl::pad_opt< pegtl::if_must< pegtl::one< ',' >, seps, expression >, sep >, key_do, statement_list< key_end > > {}; - struct for_statement_two : pegtl::seq< name_list_must, seps, key_in, seps, expr_list_must, seps, key_do, statement_list< key_end > > {}; - struct for_statement : pegtl::if_must< key_for, seps, pegtl::sor< for_statement_one, for_statement_two > > {}; + struct for_statement_one : pegtl::seq< pegtl::one< '=' >, seps, expression, seps, pegtl::one< ',' >, seps, expression, pegtl::pad_opt< pegtl::if_must< pegtl::one< ',' >, seps, expression >, sep > > {}; + struct for_statement_two : pegtl::seq< pegtl::opt< pegtl::if_must< pegtl::one< ',' >, name_list_must, seps > >, key_in, seps, expr_list_must, seps > {}; + struct for_statement : pegtl::if_must< key_for, seps, name, seps, pegtl::sor< for_statement_one, for_statement_two >, key_do, statement_list< key_end > > {}; struct assignment_variable_list : pegtl::list_must< variable, pegtl::one< ',' >, sep > {}; struct assignments_one : pegtl::if_must< pegtl::one< '=' >, seps, expr_list_must > {}; From 5e63cff6eb0ad0a4d2c66f3045335af3eaae3222 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 4 Aug 2017 14:10:55 +0200 Subject: [PATCH 2/2] Fix an error in the Lua for statement refactoring. --- src/example/pegtl/lua53_parse.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/example/pegtl/lua53_parse.cpp b/src/example/pegtl/lua53_parse.cpp index 5dc39a111..f968095e7 100644 --- a/src/example/pegtl/lua53_parse.cpp +++ b/src/example/pegtl/lua53_parse.cpp @@ -301,7 +301,7 @@ namespace lua53 struct if_statement : pegtl::if_must< key_if, seps, expression, seps, key_then, statement_list< at_elseif_else_end >, seps, pegtl::until< pegtl::sor< else_statement, key_end >, elseif_statement, seps > > {}; struct for_statement_one : pegtl::seq< pegtl::one< '=' >, seps, expression, seps, pegtl::one< ',' >, seps, expression, pegtl::pad_opt< pegtl::if_must< pegtl::one< ',' >, seps, expression >, sep > > {}; - struct for_statement_two : pegtl::seq< pegtl::opt< pegtl::if_must< pegtl::one< ',' >, name_list_must, seps > >, key_in, seps, expr_list_must, seps > {}; + struct for_statement_two : pegtl::seq< pegtl::opt< pegtl::if_must< pegtl::one< ',' >, seps, name_list_must, seps > >, key_in, seps, expr_list_must, seps > {}; struct for_statement : pegtl::if_must< key_for, seps, name, seps, pegtl::sor< for_statement_one, for_statement_two >, key_do, statement_list< key_end > > {}; struct assignment_variable_list : pegtl::list_must< variable, pegtl::one< ',' >, sep > {};