xaizek / zograscope (License: AGPLv3 only) (since 2018-12-07)
Mainly a syntax-aware diff that also provides a number of additional tools.
Commit 34eb6ea367ce776a0325d7aa23e2169c192452fc

Fix parsing of multiplication expr in C
It was present in the output, but ignored during comparison.

There are a bunch of tests because they parsing issue turned out to skew
comparison in weird ways. Some results are substantially better now.
Author: xaizek
Author date (UTC): 2023-04-02 15:43
Committer name: xaizek
Committer date (UTC): 2023-04-02 16:24
Parent(s): 5c134f6072dd9d9a57b3ca0d1fb023d9a110f244
Signing key: 99DC5E4DB05F6BE2
Tree: e9b7ac11d25778f1647c3e03af1984563e82855c
File Lines added Lines deleted
src/c/c11-parser.ypp 4 2
tests/c/c-parsing.cpp 101 0
File src/c/c11-parser.ypp changed (mode: 100644) (index 8424eda..3ec5048)
... ... unary_operator
440 440 /* ( type-name ) cast-expression */ /* ( type-name ) cast-expression */
441 441 cast_expression cast_expression
442 442 : unary_expression %dprec 1 : unary_expression %dprec 1
443 { $$ = tb->addNode($1, @1); }
443 { $$ = tb->addNode({ tb->addNode($1, @1) },
444 +C11SType::TemporaryContainer); }
444 445 | '(' type_name ')' cast_expression %dprec 2 | '(' type_name ')' cast_expression %dprec 2
445 446 { $$ = tb->addNode({ { $$ = tb->addNode({
446 447 tb->addNode({ tb->addNode({
 
... ... cast_expression
460 461 /* multiplicative-expression % cast-expression */ /* multiplicative-expression % cast-expression */
461 462 multiplicative_expression multiplicative_expression
462 463 : cast_expression %dprec 2 : cast_expression %dprec 2
463 { $$ = tb->addNode({ tb->addNode($1, @1) }); }
464 { $$ = tb->addNode({ tb->addNode($1, @1) },
465 +C11SType::TemporaryContainer); }
464 466 | multiplicative_expression '*' cast_expression %dprec 1 | multiplicative_expression '*' cast_expression %dprec 1
465 467 { $$ = tb->append($1, { tb->addNode($2, @2), tb->addNode($3, @3) }); } { $$ = tb->append($1, { tb->addNode($2, @2), tb->addNode($3, @3) }); }
466 468 | multiplicative_expression '/' cast_expression | multiplicative_expression '/' cast_expression
File tests/c/c-parsing.cpp changed (mode: 100644) (index a3d1131..6e885d8)
... ... TEST_CASE("Argument list is decomposed", "[comparison][parsing]")
329 329 } }
330 330 )", false); )", false);
331 331
332 diffC(R"(
333 void f() {
334 fprintf(fp, "%s\n",
335 hist->items[i] /// Deletions
336 );
337 }
338 )", R"(
339 void f() {
340 fprintf(fp, "%s\n",
341 hist->items[i].text /// Additions
342 );
343 }
344 )", false);
345
346 diffC(R"(
347 void f() {
348 set_colorscheme(
349 cmd_info->argv[0] /// Deletions
350 );
351 }
352 )", R"(
353 void f() {
354 set_colorscheme(
355 cmd_info->argv /// Additions
356 );
357 }
358 )", false);
359
332 360 diffC(R"( diffC(R"(
333 361 void f() { void f() {
334 362 function(firstArg); function(firstArg);
 
... ... TEST_CASE("Inversion of relatively complex condition", "[comparison][parsing]")
789 817 )", true); )", true);
790 818 } }
791 819
820 TEST_CASE("Reordering of conditionals", "[comparison][parsing]")
821 {
822 diffC(R"(
823 void f() {
824 if (
825 cfg_confirm_delete(0) /// Moves
826 &&
827 !curr_stats.confirmed
828 && /// Moves
829 (ops == NULL || !ops->bg) /// Moves
830 ) {
831 }
832 }
833 )", R"(
834 void f() {
835 if (
836 (ops == NULL || !ops->bg) /// Moves
837 &&
838 cfg_confirm_delete(0) /// Moves
839 && /// Moves
840 !curr_stats.confirmed
841 ) {
842 }
843 }
844 )", true);
845 }
846
847 TEST_CASE("Condition replacement", "[comparison][parsing]")
848 {
849 diffC(R"(
850 void f() {
851 if (cfg.use_system_calls
852 &&
853 !is_dir(fname) /// Deletions
854 &&
855 !is_dir(caused_by) /// Deletions
856 ) {
857 responses[i++] = append;
858 }
859 }
860 )", R"(
861 void f() {
862 if (cfg.use_system_calls
863 &&
864 is_regular_file_noderef(fname) /// Additions
865 &&
866 is_regular_file_noderef(caused_by) /// Additions
867 ) {
868 responses[i++] = append;
869 }
870 }
871 )", true);
872 }
873
792 874 TEST_CASE("Switch and label statements are decomposed", "[comparison][parsing]") TEST_CASE("Switch and label statements are decomposed", "[comparison][parsing]")
793 875 { {
794 876 diffC(R"( diffC(R"(
 
... ... TEST_CASE("Blocks are spliced into for statements", "[comparison][parsing]")
988 1070 } }
989 1071 )", true); )", true);
990 1072 } }
1073
1074 TEST_CASE("Multiply operator preserves its subexprs", "[comparison][parsing]")
1075 {
1076 diffC(R"(
1077 void f() {
1078 int var = 2 +
1079 2
1080 /3 /// Updates
1081 ;
1082 }
1083 )", R"(
1084 void f() {
1085 int var = 2 +
1086 2
1087 *8 /// Updates
1088 ;
1089 }
1090 )", true);
1091 }
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/zograscope

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/zograscope

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master