From fff52cd5a567ec541cd487b9fee2d89bf9b6f6eb Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Mon, 9 Sep 2019 10:19:58 -0600 Subject: base (aapl, colm, ragel) test cases building --- test/trans.d/.gitignore | 4 + test/trans.d/Makefile | 30 + test/trans.d/actparams.cc | 63 + test/trans.d/case/any1.rl | 17 + test/trans.d/case/any1_asm.rl | 118 ++ test/trans.d/case/any1_c.rl | 62 + test/trans.d/case/any1_crack.rl | 47 + test/trans.d/case/any1_cs.rl | 67 ++ test/trans.d/case/any1_d.rl | 66 ++ test/trans.d/case/any1_go.rl | 52 + test/trans.d/case/any1_java.rl | 63 + test/trans.d/case/any1_julia.rl | 37 + test/trans.d/case/any1_ocaml.rl | 39 + test/trans.d/case/any1_ruby.rl | 45 + test/trans.d/case/any1_rust.rl | 44 + test/trans.d/case/atoi1.rl | 67 ++ test/trans.d/case/atoi1_asm.rl | 246 ++++ test/trans.d/case/atoi1_c.rl | 96 ++ test/trans.d/case/atoi1_crack.rl | 81 ++ test/trans.d/case/atoi1_cs.rl | 99 ++ test/trans.d/case/atoi1_d.rl | 99 ++ test/trans.d/case/atoi1_go.rl | 83 ++ test/trans.d/case/atoi1_java.rl | 97 ++ test/trans.d/case/atoi1_julia.rl | 70 ++ test/trans.d/case/atoi1_ocaml.rl | 74 ++ test/trans.d/case/atoi1_ruby.rl | 78 ++ test/trans.d/case/atoi1_rust.rl | 78 ++ test/trans.d/case/atoi2.rl | 81 ++ test/trans.d/case/atoi2_asm.rl | 261 +++++ test/trans.d/case/atoi2_c.rl | 111 ++ test/trans.d/case/atoi2_crack.rl | 96 ++ test/trans.d/case/atoi2_cs.rl | 114 ++ test/trans.d/case/atoi2_d.rl | 114 ++ test/trans.d/case/atoi2_go.rl | 98 ++ test/trans.d/case/atoi2_java.rl | 112 ++ test/trans.d/case/atoi2_julia.rl | 85 ++ test/trans.d/case/atoi2_ocaml.rl | 89 ++ test/trans.d/case/atoi2_ruby.rl | 93 ++ test/trans.d/case/atoi2_rust.rl | 93 ++ test/trans.d/case/call4.rl | 39 + test/trans.d/case/call4_asm.rl | 180 +++ test/trans.d/case/call4_c.rl | 76 ++ test/trans.d/case/call4_crack.rl | 61 + test/trans.d/case/call4_cs.rl | 79 ++ test/trans.d/case/call4_d.rl | 78 ++ test/trans.d/case/call4_go.rl | 70 ++ test/trans.d/case/call4_java.rl | 77 ++ test/trans.d/case/call4_julia.rl | 51 + test/trans.d/case/call4_rust.rl | 58 + test/trans.d/case/caseindep.rl | 54 + test/trans.d/case/caseindep_asm.rl | 170 +++ test/trans.d/case/caseindep_c.rl | 84 ++ test/trans.d/case/caseindep_crack.rl | 69 ++ test/trans.d/case/caseindep_cs.rl | 89 ++ test/trans.d/case/caseindep_d.rl | 88 ++ test/trans.d/case/caseindep_go.rl | 74 ++ test/trans.d/case/caseindep_java.rl | 85 ++ test/trans.d/case/caseindep_julia.rl | 59 + test/trans.d/case/caseindep_ocaml.rl | 61 + test/trans.d/case/caseindep_ruby.rl | 67 ++ test/trans.d/case/caseindep_rust.rl | 66 ++ test/trans.d/case/clang4.rl | 187 +++ test/trans.d/case/clang4_asm.rl | 603 ++++++++++ test/trans.d/case/clang4_c.rl | 202 ++++ test/trans.d/case/clang4_crack.rl | 186 +++ test/trans.d/case/clang4_cs.rl | 169 +++ test/trans.d/case/clang4_d.rl | 176 +++ test/trans.d/case/clang4_go.rl | 151 +++ test/trans.d/case/clang4_java.rl | 203 ++++ test/trans.d/case/clang4_julia.rl | 175 +++ test/trans.d/case/clang4_ocaml.rl | 183 +++ test/trans.d/case/clang4_ruby.rl | 184 +++ test/trans.d/case/clang4_rust.rl | 182 +++ test/trans.d/case/cond1.rl | 84 ++ test/trans.d/case/cond1_asm.rl | 319 ++++++ test/trans.d/case/cond1_c.rl | 121 ++ test/trans.d/case/cond1_crack.rl | 106 ++ test/trans.d/case/cond1_cs.rl | 123 ++ test/trans.d/case/cond1_d.rl | 122 ++ test/trans.d/case/cond1_go.rl | 103 ++ test/trans.d/case/cond1_java.rl | 122 ++ test/trans.d/case/cond1_julia.rl | 90 ++ test/trans.d/case/cond1_ocaml.rl | 104 ++ test/trans.d/case/cond1_ruby.rl | 98 ++ test/trans.d/case/cond1_rust.rl | 103 ++ test/trans.d/case/cond7.rl | 80 ++ test/trans.d/case/cond7_asm.rl | 234 ++++ test/trans.d/case/cond7_c.rl | 87 ++ test/trans.d/case/cond7_crack.rl | 72 ++ test/trans.d/case/cond7_cs.rl | 86 ++ test/trans.d/case/cond7_d.rl | 87 ++ test/trans.d/case/cond7_go.rl | 71 ++ test/trans.d/case/cond7_java.rl | 88 ++ test/trans.d/case/cond7_julia.rl | 62 + test/trans.d/case/cond7_ocaml.rl | 64 ++ test/trans.d/case/cond7_ruby.rl | 70 ++ test/trans.d/case/cond7_rust.rl | 69 ++ test/trans.d/case/cppscan6.rl | 359 ++++++ test/trans.d/case/cppscan6_asm.rl | 1908 +++++++++++++++++++++++++++++++ test/trans.d/case/cppscan6_c.rl | 278 +++++ test/trans.d/case/cppscan6_crack.rl | 323 ++++++ test/trans.d/case/cppscan6_cs.rl | 195 ++++ test/trans.d/case/cppscan6_d.rl | 195 ++++ test/trans.d/case/cppscan6_go.rl | 152 +++ test/trans.d/case/cppscan6_java.rl | 339 ++++++ test/trans.d/case/cppscan6_julia.rl | 281 +++++ test/trans.d/case/cppscan6_ocaml.rl | 255 +++++ test/trans.d/case/cppscan6_ruby.rl | 318 ++++++ test/trans.d/case/cppscan6_rust.rl | 406 +++++++ test/trans.d/case/curs1.rl | 34 + test/trans.d/case/curs1_asm.rl | 171 +++ test/trans.d/case/curs1_c.rl | 73 ++ test/trans.d/case/curs1_crack.rl | 58 + test/trans.d/case/curs1_cs.rl | 76 ++ test/trans.d/case/curs1_d.rl | 75 ++ test/trans.d/case/curs1_go.rl | 67 ++ test/trans.d/case/curs1_java.rl | 74 ++ test/trans.d/case/curs1_julia.rl | 48 + test/trans.d/case/curs1_ocaml.rl | 52 + test/trans.d/case/curs1_ruby.rl | 56 + test/trans.d/case/curs1_rust.rl | 55 + test/trans.d/case/empty1.rl | 15 + test/trans.d/case/empty1_asm.rl | 115 ++ test/trans.d/case/empty1_c.rl | 61 + test/trans.d/case/empty1_crack.rl | 46 + test/trans.d/case/empty1_cs.rl | 66 ++ test/trans.d/case/empty1_d.rl | 65 ++ test/trans.d/case/empty1_go.rl | 51 + test/trans.d/case/empty1_java.rl | 62 + test/trans.d/case/empty1_julia.rl | 36 + test/trans.d/case/empty1_ocaml.rl | 38 + test/trans.d/case/empty1_ruby.rl | 44 + test/trans.d/case/empty1_rust.rl | 43 + test/trans.d/case/eofact.rl | 51 + test/trans.d/case/eofact_asm.rl | 196 ++++ test/trans.d/case/eofact_c.rl | 84 ++ test/trans.d/case/eofact_crack.rl | 69 ++ test/trans.d/case/eofact_cs.rl | 84 ++ test/trans.d/case/eofact_d.rl | 84 ++ test/trans.d/case/eofact_go.rl | 70 ++ test/trans.d/case/eofact_java.rl | 85 ++ test/trans.d/case/eofact_julia.rl | 58 + test/trans.d/case/eofact_ocaml.rl | 61 + test/trans.d/case/eofact_ruby.rl | 66 ++ test/trans.d/case/eofact_rust.rl | 65 ++ test/trans.d/case/erract2.rl | 90 ++ test/trans.d/case/erract2_asm.rl | 259 +++++ test/trans.d/case/erract2_c.rl | 95 ++ test/trans.d/case/erract2_crack.rl | 80 ++ test/trans.d/case/erract2_cs.rl | 91 ++ test/trans.d/case/erract2_d.rl | 91 ++ test/trans.d/case/erract2_go.rl | 77 ++ test/trans.d/case/erract2_java.rl | 96 ++ test/trans.d/case/erract2_julia.rl | 69 ++ test/trans.d/case/erract2_ocaml.rl | 72 ++ test/trans.d/case/erract2_ruby.rl | 77 ++ test/trans.d/case/erract2_rust.rl | 76 ++ test/trans.d/case/goto1.rl | 37 + test/trans.d/case/goto1_asm.rl | 187 +++ test/trans.d/case/goto1_c.rl | 75 ++ test/trans.d/case/goto1_crack.rl | 60 + test/trans.d/case/goto1_cs.rl | 78 ++ test/trans.d/case/goto1_d.rl | 77 ++ test/trans.d/case/goto1_go.rl | 69 ++ test/trans.d/case/goto1_java.rl | 76 ++ test/trans.d/case/goto1_julia.rl | 50 + test/trans.d/case/goto1_rust.rl | 57 + test/trans.d/case/gotocallret1.rl | 117 ++ test/trans.d/case/gotocallret1_asm.rl | 280 +++++ test/trans.d/case/gotocallret1_c.rl | 122 ++ test/trans.d/case/gotocallret1_crack.rl | 107 ++ test/trans.d/case/gotocallret1_cs.rl | 123 ++ test/trans.d/case/gotocallret1_d.rl | 123 ++ test/trans.d/case/gotocallret1_go.rl | 116 ++ test/trans.d/case/gotocallret1_java.rl | 123 ++ test/trans.d/case/gotocallret1_julia.rl | 94 ++ test/trans.d/case/gotocallret1_rust.rl | 103 ++ test/trans.d/case/gotocallret2.rl | 78 ++ test/trans.d/case/gotocallret2_asm.rl | 484 ++++++++ test/trans.d/case/gotocallret2_c.rl | 135 +++ test/trans.d/case/gotocallret2_crack.rl | 122 ++ test/trans.d/case/gotocallret2_cs.rl | 123 ++ test/trans.d/case/gotocallret2_d.rl | 123 ++ test/trans.d/case/gotocallret2_go.rl | 122 ++ test/trans.d/case/gotocallret2_java.rl | 138 +++ test/trans.d/case/gotocallret2_julia.rl | 106 ++ test/trans.d/case/gotocallret2_rust.rl | 118 ++ test/trans.d/case/gotocallret3.rl | 121 ++ test/trans.d/case/gotocallret3_asm.rl | 292 +++++ test/trans.d/case/gotocallret3_c.rl | 123 ++ test/trans.d/case/gotocallret3_crack.rl | 108 ++ test/trans.d/case/gotocallret3_cs.rl | 123 ++ test/trans.d/case/gotocallret3_d.rl | 123 ++ test/trans.d/case/gotocallret3_go.rl | 116 ++ test/trans.d/case/gotocallret3_java.rl | 124 ++ test/trans.d/case/gotocallret3_julia.rl | 95 ++ test/trans.d/case/gotocallret3_ocaml.rl | 104 ++ test/trans.d/case/gotocallret3_ruby.rl | 103 ++ test/trans.d/case/gotocallret3_rust.rl | 104 ++ test/trans.d/case/ncall1.rl | 38 + test/trans.d/case/ncall1_asm.rl | 180 +++ test/trans.d/case/ncall1_c.rl | 76 ++ test/trans.d/case/ncall1_crack.rl | 61 + test/trans.d/case/ncall1_cs.rl | 79 ++ test/trans.d/case/ncall1_d.rl | 78 ++ test/trans.d/case/ncall1_go.rl | 70 ++ test/trans.d/case/ncall1_java.rl | 77 ++ test/trans.d/case/ncall1_julia.rl | 51 + test/trans.d/case/ncall1_ocaml.rl | 57 + test/trans.d/case/ncall1_ruby.rl | 59 + test/trans.d/case/ncall1_rust.rl | 58 + test/trans.d/case/next1.rl | 36 + test/trans.d/case/next1_asm.rl | 187 +++ test/trans.d/case/next1_c.rl | 75 ++ test/trans.d/case/next1_crack.rl | 60 + test/trans.d/case/next1_cs.rl | 78 ++ test/trans.d/case/next1_d.rl | 77 ++ test/trans.d/case/next1_go.rl | 69 ++ test/trans.d/case/next1_java.rl | 76 ++ test/trans.d/case/next1_julia.rl | 50 + test/trans.d/case/next1_ocaml.rl | 56 + test/trans.d/case/next1_ruby.rl | 58 + test/trans.d/case/next1_rust.rl | 57 + test/trans.d/case/next2.rl | 64 ++ test/trans.d/case/next2_asm.rl | 256 +++++ test/trans.d/case/next2_c.rl | 94 ++ test/trans.d/case/next2_crack.rl | 79 ++ test/trans.d/case/next2_cs.rl | 96 ++ test/trans.d/case/next2_d.rl | 95 ++ test/trans.d/case/next2_go.rl | 92 ++ test/trans.d/case/next2_java.rl | 95 ++ test/trans.d/case/next2_julia.rl | 68 ++ test/trans.d/case/next2_ocaml.rl | 78 ++ test/trans.d/case/next2_ruby.rl | 76 ++ test/trans.d/case/next2_rust.rl | 76 ++ test/trans.d/case/patact.rl | 99 ++ test/trans.d/case/patact_asm.rl | 426 +++++++ test/trans.d/case/patact_c.rl | 120 ++ test/trans.d/case/patact_crack.rl | 107 ++ test/trans.d/case/patact_cs.rl | 106 ++ test/trans.d/case/patact_d.rl | 106 ++ test/trans.d/case/patact_go.rl | 104 ++ test/trans.d/case/patact_java.rl | 123 ++ test/trans.d/case/patact_julia.rl | 94 ++ test/trans.d/case/patact_ocaml.rl | 97 ++ test/trans.d/case/patact_ruby.rl | 102 ++ test/trans.d/case/patact_rust.rl | 103 ++ test/trans.d/case/rangei.rl | 28 + test/trans.d/case/rangei_asm.rl | 131 +++ test/trans.d/case/rangei_c.rl | 71 ++ test/trans.d/case/rangei_crack.rl | 56 + test/trans.d/case/rangei_cs.rl | 76 ++ test/trans.d/case/rangei_d.rl | 75 ++ test/trans.d/case/rangei_go.rl | 61 + test/trans.d/case/rangei_java.rl | 72 ++ test/trans.d/case/rangei_julia.rl | 46 + test/trans.d/case/rangei_ocaml.rl | 48 + test/trans.d/case/rangei_ruby.rl | 54 + test/trans.d/case/rangei_rust.rl | 53 + test/trans.d/case/scan1.rl | 70 ++ test/trans.d/case/scan1_asm.rl | 394 +++++++ test/trans.d/case/scan1_c.rl | 114 ++ test/trans.d/case/scan1_crack.rl | 101 ++ test/trans.d/case/scan1_cs.rl | 103 ++ test/trans.d/case/scan1_d.rl | 103 ++ test/trans.d/case/scan1_go.rl | 84 ++ test/trans.d/case/scan1_java.rl | 117 ++ test/trans.d/case/scan1_julia.rl | 83 ++ test/trans.d/case/scan1_ocaml.rl | 96 ++ test/trans.d/case/scan1_ruby.rl | 91 ++ test/trans.d/case/scan1_rust.rl | 97 ++ test/trans.d/case/scan2.rl | 34 + test/trans.d/case/scan2_asm.rl | 168 +++ test/trans.d/case/scan2_c.rl | 75 ++ test/trans.d/case/scan2_crack.rl | 62 + test/trans.d/case/scan2_cs.rl | 76 ++ test/trans.d/case/scan2_d.rl | 76 ++ test/trans.d/case/scan2_go.rl | 62 + test/trans.d/case/scan2_java.rl | 78 ++ test/trans.d/case/scan2_julia.rl | 49 + test/trans.d/case/scan2_ocaml.rl | 52 + test/trans.d/case/scan2_ruby.rl | 57 + test/trans.d/case/scan2_rust.rl | 58 + test/trans.d/case/scan3.rl | 33 + test/trans.d/case/scan3_asm.rl | 166 +++ test/trans.d/case/scan3_c.rl | 73 ++ test/trans.d/case/scan3_crack.rl | 60 + test/trans.d/case/scan3_cs.rl | 74 ++ test/trans.d/case/scan3_d.rl | 74 ++ test/trans.d/case/scan3_go.rl | 60 + test/trans.d/case/scan3_java.rl | 76 ++ test/trans.d/case/scan3_julia.rl | 47 + test/trans.d/case/scan3_ocaml.rl | 50 + test/trans.d/case/scan3_ruby.rl | 55 + test/trans.d/case/scan3_rust.rl | 56 + test/trans.d/case/scan4.rl | 34 + test/trans.d/case/scan4_asm.rl | 156 +++ test/trans.d/case/scan4_c.rl | 74 ++ test/trans.d/case/scan4_crack.rl | 61 + test/trans.d/case/scan4_cs.rl | 76 ++ test/trans.d/case/scan4_d.rl | 76 ++ test/trans.d/case/scan4_go.rl | 62 + test/trans.d/case/scan4_java.rl | 77 ++ test/trans.d/case/scan4_julia.rl | 48 + test/trans.d/case/scan4_ocaml.rl | 51 + test/trans.d/case/scan4_ruby.rl | 56 + test/trans.d/case/scan4_rust.rl | 57 + test/trans.d/case/stateact1.rl | 47 + test/trans.d/case/stateact1_asm.rl | 208 ++++ test/trans.d/case/stateact1_c.rl | 87 ++ test/trans.d/case/stateact1_crack.rl | 72 ++ test/trans.d/case/stateact1_cs.rl | 86 ++ test/trans.d/case/stateact1_d.rl | 85 ++ test/trans.d/case/stateact1_go.rl | 72 ++ test/trans.d/case/stateact1_java.rl | 88 ++ test/trans.d/case/stateact1_julia.rl | 62 + test/trans.d/case/stateact1_ocaml.rl | 64 ++ test/trans.d/case/stateact1_ruby.rl | 70 ++ test/trans.d/case/stateact1_rust.rl | 69 ++ test/trans.d/case/targs1.rl | 35 + test/trans.d/case/targs1_asm.rl | 172 +++ test/trans.d/case/targs1_c.rl | 74 ++ test/trans.d/case/targs1_crack.rl | 59 + test/trans.d/case/targs1_cs.rl | 77 ++ test/trans.d/case/targs1_d.rl | 76 ++ test/trans.d/case/targs1_go.rl | 68 ++ test/trans.d/case/targs1_java.rl | 75 ++ test/trans.d/case/targs1_julia.rl | 49 + test/trans.d/case/targs1_ocaml.rl | 53 + test/trans.d/case/targs1_ruby.rl | 57 + test/trans.d/case/targs1_rust.rl | 56 + test/trans.d/case/zlen1.rl | 15 + test/trans.d/case/zlen1_asm.rl | 115 ++ test/trans.d/case/zlen1_c.rl | 61 + test/trans.d/case/zlen1_crack.rl | 46 + test/trans.d/case/zlen1_cs.rl | 66 ++ test/trans.d/case/zlen1_d.rl | 65 ++ test/trans.d/case/zlen1_go.rl | 51 + test/trans.d/case/zlen1_java.rl | 62 + test/trans.d/case/zlen1_julia.rl | 36 + test/trans.d/case/zlen1_ocaml.rl | 38 + test/trans.d/case/zlen1_ruby.rl | 44 + test/trans.d/case/zlen1_rust.rl | 43 + test/trans.d/gentests | 45 + test/trans.d/main.c | 16 + test/trans.d/ragel-c.lm | 175 +++ test/trans.d/ragel-crack.lm | 150 +++ test/trans.d/ragel-ocaml.lm | 147 +++ test/trans.d/ragel-ruby.lm | 146 +++ test/trans.d/ragel.lm | 559 +++++++++ test/trans.d/trans-asm.lm | 601 ++++++++++ test/trans.d/trans-c.lm | 346 ++++++ test/trans.d/trans-crack.lm | 346 ++++++ test/trans.d/trans-csharp.lm | 346 ++++++ test/trans.d/trans-d.lm | 332 ++++++ test/trans.d/trans-go.lm | 322 ++++++ test/trans.d/trans-java.lm | 346 ++++++ test/trans.d/trans-julia.lm | 332 ++++++ test/trans.d/trans-ocaml.lm | 362 ++++++ test/trans.d/trans-ruby.lm | 336 ++++++ test/trans.d/trans-rust.lm | 344 ++++++ test/trans.d/trans.lm | 366 ++++++ 362 files changed, 41327 insertions(+) create mode 100644 test/trans.d/.gitignore create mode 100644 test/trans.d/Makefile create mode 100644 test/trans.d/actparams.cc create mode 100644 test/trans.d/case/any1.rl create mode 100644 test/trans.d/case/any1_asm.rl create mode 100644 test/trans.d/case/any1_c.rl create mode 100644 test/trans.d/case/any1_crack.rl create mode 100644 test/trans.d/case/any1_cs.rl create mode 100644 test/trans.d/case/any1_d.rl create mode 100644 test/trans.d/case/any1_go.rl create mode 100644 test/trans.d/case/any1_java.rl create mode 100644 test/trans.d/case/any1_julia.rl create mode 100644 test/trans.d/case/any1_ocaml.rl create mode 100644 test/trans.d/case/any1_ruby.rl create mode 100644 test/trans.d/case/any1_rust.rl create mode 100644 test/trans.d/case/atoi1.rl create mode 100644 test/trans.d/case/atoi1_asm.rl create mode 100644 test/trans.d/case/atoi1_c.rl create mode 100644 test/trans.d/case/atoi1_crack.rl create mode 100644 test/trans.d/case/atoi1_cs.rl create mode 100644 test/trans.d/case/atoi1_d.rl create mode 100644 test/trans.d/case/atoi1_go.rl create mode 100644 test/trans.d/case/atoi1_java.rl create mode 100644 test/trans.d/case/atoi1_julia.rl create mode 100644 test/trans.d/case/atoi1_ocaml.rl create mode 100644 test/trans.d/case/atoi1_ruby.rl create mode 100644 test/trans.d/case/atoi1_rust.rl create mode 100644 test/trans.d/case/atoi2.rl create mode 100644 test/trans.d/case/atoi2_asm.rl create mode 100644 test/trans.d/case/atoi2_c.rl create mode 100644 test/trans.d/case/atoi2_crack.rl create mode 100644 test/trans.d/case/atoi2_cs.rl create mode 100644 test/trans.d/case/atoi2_d.rl create mode 100644 test/trans.d/case/atoi2_go.rl create mode 100644 test/trans.d/case/atoi2_java.rl create mode 100644 test/trans.d/case/atoi2_julia.rl create mode 100644 test/trans.d/case/atoi2_ocaml.rl create mode 100644 test/trans.d/case/atoi2_ruby.rl create mode 100644 test/trans.d/case/atoi2_rust.rl create mode 100644 test/trans.d/case/call4.rl create mode 100644 test/trans.d/case/call4_asm.rl create mode 100644 test/trans.d/case/call4_c.rl create mode 100644 test/trans.d/case/call4_crack.rl create mode 100644 test/trans.d/case/call4_cs.rl create mode 100644 test/trans.d/case/call4_d.rl create mode 100644 test/trans.d/case/call4_go.rl create mode 100644 test/trans.d/case/call4_java.rl create mode 100644 test/trans.d/case/call4_julia.rl create mode 100644 test/trans.d/case/call4_rust.rl create mode 100644 test/trans.d/case/caseindep.rl create mode 100644 test/trans.d/case/caseindep_asm.rl create mode 100644 test/trans.d/case/caseindep_c.rl create mode 100644 test/trans.d/case/caseindep_crack.rl create mode 100644 test/trans.d/case/caseindep_cs.rl create mode 100644 test/trans.d/case/caseindep_d.rl create mode 100644 test/trans.d/case/caseindep_go.rl create mode 100644 test/trans.d/case/caseindep_java.rl create mode 100644 test/trans.d/case/caseindep_julia.rl create mode 100644 test/trans.d/case/caseindep_ocaml.rl create mode 100644 test/trans.d/case/caseindep_ruby.rl create mode 100644 test/trans.d/case/caseindep_rust.rl create mode 100644 test/trans.d/case/clang4.rl create mode 100644 test/trans.d/case/clang4_asm.rl create mode 100644 test/trans.d/case/clang4_c.rl create mode 100644 test/trans.d/case/clang4_crack.rl create mode 100644 test/trans.d/case/clang4_cs.rl create mode 100644 test/trans.d/case/clang4_d.rl create mode 100644 test/trans.d/case/clang4_go.rl create mode 100644 test/trans.d/case/clang4_java.rl create mode 100644 test/trans.d/case/clang4_julia.rl create mode 100644 test/trans.d/case/clang4_ocaml.rl create mode 100644 test/trans.d/case/clang4_ruby.rl create mode 100644 test/trans.d/case/clang4_rust.rl create mode 100644 test/trans.d/case/cond1.rl create mode 100644 test/trans.d/case/cond1_asm.rl create mode 100644 test/trans.d/case/cond1_c.rl create mode 100644 test/trans.d/case/cond1_crack.rl create mode 100644 test/trans.d/case/cond1_cs.rl create mode 100644 test/trans.d/case/cond1_d.rl create mode 100644 test/trans.d/case/cond1_go.rl create mode 100644 test/trans.d/case/cond1_java.rl create mode 100644 test/trans.d/case/cond1_julia.rl create mode 100644 test/trans.d/case/cond1_ocaml.rl create mode 100644 test/trans.d/case/cond1_ruby.rl create mode 100644 test/trans.d/case/cond1_rust.rl create mode 100644 test/trans.d/case/cond7.rl create mode 100644 test/trans.d/case/cond7_asm.rl create mode 100644 test/trans.d/case/cond7_c.rl create mode 100644 test/trans.d/case/cond7_crack.rl create mode 100644 test/trans.d/case/cond7_cs.rl create mode 100644 test/trans.d/case/cond7_d.rl create mode 100644 test/trans.d/case/cond7_go.rl create mode 100644 test/trans.d/case/cond7_java.rl create mode 100644 test/trans.d/case/cond7_julia.rl create mode 100644 test/trans.d/case/cond7_ocaml.rl create mode 100644 test/trans.d/case/cond7_ruby.rl create mode 100644 test/trans.d/case/cond7_rust.rl create mode 100644 test/trans.d/case/cppscan6.rl create mode 100644 test/trans.d/case/cppscan6_asm.rl create mode 100644 test/trans.d/case/cppscan6_c.rl create mode 100644 test/trans.d/case/cppscan6_crack.rl create mode 100644 test/trans.d/case/cppscan6_cs.rl create mode 100644 test/trans.d/case/cppscan6_d.rl create mode 100644 test/trans.d/case/cppscan6_go.rl create mode 100644 test/trans.d/case/cppscan6_java.rl create mode 100644 test/trans.d/case/cppscan6_julia.rl create mode 100644 test/trans.d/case/cppscan6_ocaml.rl create mode 100644 test/trans.d/case/cppscan6_ruby.rl create mode 100644 test/trans.d/case/cppscan6_rust.rl create mode 100644 test/trans.d/case/curs1.rl create mode 100644 test/trans.d/case/curs1_asm.rl create mode 100644 test/trans.d/case/curs1_c.rl create mode 100644 test/trans.d/case/curs1_crack.rl create mode 100644 test/trans.d/case/curs1_cs.rl create mode 100644 test/trans.d/case/curs1_d.rl create mode 100644 test/trans.d/case/curs1_go.rl create mode 100644 test/trans.d/case/curs1_java.rl create mode 100644 test/trans.d/case/curs1_julia.rl create mode 100644 test/trans.d/case/curs1_ocaml.rl create mode 100644 test/trans.d/case/curs1_ruby.rl create mode 100644 test/trans.d/case/curs1_rust.rl create mode 100644 test/trans.d/case/empty1.rl create mode 100644 test/trans.d/case/empty1_asm.rl create mode 100644 test/trans.d/case/empty1_c.rl create mode 100644 test/trans.d/case/empty1_crack.rl create mode 100644 test/trans.d/case/empty1_cs.rl create mode 100644 test/trans.d/case/empty1_d.rl create mode 100644 test/trans.d/case/empty1_go.rl create mode 100644 test/trans.d/case/empty1_java.rl create mode 100644 test/trans.d/case/empty1_julia.rl create mode 100644 test/trans.d/case/empty1_ocaml.rl create mode 100644 test/trans.d/case/empty1_ruby.rl create mode 100644 test/trans.d/case/empty1_rust.rl create mode 100644 test/trans.d/case/eofact.rl create mode 100644 test/trans.d/case/eofact_asm.rl create mode 100644 test/trans.d/case/eofact_c.rl create mode 100644 test/trans.d/case/eofact_crack.rl create mode 100644 test/trans.d/case/eofact_cs.rl create mode 100644 test/trans.d/case/eofact_d.rl create mode 100644 test/trans.d/case/eofact_go.rl create mode 100644 test/trans.d/case/eofact_java.rl create mode 100644 test/trans.d/case/eofact_julia.rl create mode 100644 test/trans.d/case/eofact_ocaml.rl create mode 100644 test/trans.d/case/eofact_ruby.rl create mode 100644 test/trans.d/case/eofact_rust.rl create mode 100644 test/trans.d/case/erract2.rl create mode 100644 test/trans.d/case/erract2_asm.rl create mode 100644 test/trans.d/case/erract2_c.rl create mode 100644 test/trans.d/case/erract2_crack.rl create mode 100644 test/trans.d/case/erract2_cs.rl create mode 100644 test/trans.d/case/erract2_d.rl create mode 100644 test/trans.d/case/erract2_go.rl create mode 100644 test/trans.d/case/erract2_java.rl create mode 100644 test/trans.d/case/erract2_julia.rl create mode 100644 test/trans.d/case/erract2_ocaml.rl create mode 100644 test/trans.d/case/erract2_ruby.rl create mode 100644 test/trans.d/case/erract2_rust.rl create mode 100644 test/trans.d/case/goto1.rl create mode 100644 test/trans.d/case/goto1_asm.rl create mode 100644 test/trans.d/case/goto1_c.rl create mode 100644 test/trans.d/case/goto1_crack.rl create mode 100644 test/trans.d/case/goto1_cs.rl create mode 100644 test/trans.d/case/goto1_d.rl create mode 100644 test/trans.d/case/goto1_go.rl create mode 100644 test/trans.d/case/goto1_java.rl create mode 100644 test/trans.d/case/goto1_julia.rl create mode 100644 test/trans.d/case/goto1_rust.rl create mode 100644 test/trans.d/case/gotocallret1.rl create mode 100644 test/trans.d/case/gotocallret1_asm.rl create mode 100644 test/trans.d/case/gotocallret1_c.rl create mode 100644 test/trans.d/case/gotocallret1_crack.rl create mode 100644 test/trans.d/case/gotocallret1_cs.rl create mode 100644 test/trans.d/case/gotocallret1_d.rl create mode 100644 test/trans.d/case/gotocallret1_go.rl create mode 100644 test/trans.d/case/gotocallret1_java.rl create mode 100644 test/trans.d/case/gotocallret1_julia.rl create mode 100644 test/trans.d/case/gotocallret1_rust.rl create mode 100644 test/trans.d/case/gotocallret2.rl create mode 100644 test/trans.d/case/gotocallret2_asm.rl create mode 100644 test/trans.d/case/gotocallret2_c.rl create mode 100644 test/trans.d/case/gotocallret2_crack.rl create mode 100644 test/trans.d/case/gotocallret2_cs.rl create mode 100644 test/trans.d/case/gotocallret2_d.rl create mode 100644 test/trans.d/case/gotocallret2_go.rl create mode 100644 test/trans.d/case/gotocallret2_java.rl create mode 100644 test/trans.d/case/gotocallret2_julia.rl create mode 100644 test/trans.d/case/gotocallret2_rust.rl create mode 100644 test/trans.d/case/gotocallret3.rl create mode 100644 test/trans.d/case/gotocallret3_asm.rl create mode 100644 test/trans.d/case/gotocallret3_c.rl create mode 100644 test/trans.d/case/gotocallret3_crack.rl create mode 100644 test/trans.d/case/gotocallret3_cs.rl create mode 100644 test/trans.d/case/gotocallret3_d.rl create mode 100644 test/trans.d/case/gotocallret3_go.rl create mode 100644 test/trans.d/case/gotocallret3_java.rl create mode 100644 test/trans.d/case/gotocallret3_julia.rl create mode 100644 test/trans.d/case/gotocallret3_ocaml.rl create mode 100644 test/trans.d/case/gotocallret3_ruby.rl create mode 100644 test/trans.d/case/gotocallret3_rust.rl create mode 100644 test/trans.d/case/ncall1.rl create mode 100644 test/trans.d/case/ncall1_asm.rl create mode 100644 test/trans.d/case/ncall1_c.rl create mode 100644 test/trans.d/case/ncall1_crack.rl create mode 100644 test/trans.d/case/ncall1_cs.rl create mode 100644 test/trans.d/case/ncall1_d.rl create mode 100644 test/trans.d/case/ncall1_go.rl create mode 100644 test/trans.d/case/ncall1_java.rl create mode 100644 test/trans.d/case/ncall1_julia.rl create mode 100644 test/trans.d/case/ncall1_ocaml.rl create mode 100644 test/trans.d/case/ncall1_ruby.rl create mode 100644 test/trans.d/case/ncall1_rust.rl create mode 100644 test/trans.d/case/next1.rl create mode 100644 test/trans.d/case/next1_asm.rl create mode 100644 test/trans.d/case/next1_c.rl create mode 100644 test/trans.d/case/next1_crack.rl create mode 100644 test/trans.d/case/next1_cs.rl create mode 100644 test/trans.d/case/next1_d.rl create mode 100644 test/trans.d/case/next1_go.rl create mode 100644 test/trans.d/case/next1_java.rl create mode 100644 test/trans.d/case/next1_julia.rl create mode 100644 test/trans.d/case/next1_ocaml.rl create mode 100644 test/trans.d/case/next1_ruby.rl create mode 100644 test/trans.d/case/next1_rust.rl create mode 100644 test/trans.d/case/next2.rl create mode 100644 test/trans.d/case/next2_asm.rl create mode 100644 test/trans.d/case/next2_c.rl create mode 100644 test/trans.d/case/next2_crack.rl create mode 100644 test/trans.d/case/next2_cs.rl create mode 100644 test/trans.d/case/next2_d.rl create mode 100644 test/trans.d/case/next2_go.rl create mode 100644 test/trans.d/case/next2_java.rl create mode 100644 test/trans.d/case/next2_julia.rl create mode 100644 test/trans.d/case/next2_ocaml.rl create mode 100644 test/trans.d/case/next2_ruby.rl create mode 100644 test/trans.d/case/next2_rust.rl create mode 100644 test/trans.d/case/patact.rl create mode 100644 test/trans.d/case/patact_asm.rl create mode 100644 test/trans.d/case/patact_c.rl create mode 100644 test/trans.d/case/patact_crack.rl create mode 100644 test/trans.d/case/patact_cs.rl create mode 100644 test/trans.d/case/patact_d.rl create mode 100644 test/trans.d/case/patact_go.rl create mode 100644 test/trans.d/case/patact_java.rl create mode 100644 test/trans.d/case/patact_julia.rl create mode 100644 test/trans.d/case/patact_ocaml.rl create mode 100644 test/trans.d/case/patact_ruby.rl create mode 100644 test/trans.d/case/patact_rust.rl create mode 100644 test/trans.d/case/rangei.rl create mode 100644 test/trans.d/case/rangei_asm.rl create mode 100644 test/trans.d/case/rangei_c.rl create mode 100644 test/trans.d/case/rangei_crack.rl create mode 100644 test/trans.d/case/rangei_cs.rl create mode 100644 test/trans.d/case/rangei_d.rl create mode 100644 test/trans.d/case/rangei_go.rl create mode 100644 test/trans.d/case/rangei_java.rl create mode 100644 test/trans.d/case/rangei_julia.rl create mode 100644 test/trans.d/case/rangei_ocaml.rl create mode 100644 test/trans.d/case/rangei_ruby.rl create mode 100644 test/trans.d/case/rangei_rust.rl create mode 100644 test/trans.d/case/scan1.rl create mode 100644 test/trans.d/case/scan1_asm.rl create mode 100644 test/trans.d/case/scan1_c.rl create mode 100644 test/trans.d/case/scan1_crack.rl create mode 100644 test/trans.d/case/scan1_cs.rl create mode 100644 test/trans.d/case/scan1_d.rl create mode 100644 test/trans.d/case/scan1_go.rl create mode 100644 test/trans.d/case/scan1_java.rl create mode 100644 test/trans.d/case/scan1_julia.rl create mode 100644 test/trans.d/case/scan1_ocaml.rl create mode 100644 test/trans.d/case/scan1_ruby.rl create mode 100644 test/trans.d/case/scan1_rust.rl create mode 100644 test/trans.d/case/scan2.rl create mode 100644 test/trans.d/case/scan2_asm.rl create mode 100644 test/trans.d/case/scan2_c.rl create mode 100644 test/trans.d/case/scan2_crack.rl create mode 100644 test/trans.d/case/scan2_cs.rl create mode 100644 test/trans.d/case/scan2_d.rl create mode 100644 test/trans.d/case/scan2_go.rl create mode 100644 test/trans.d/case/scan2_java.rl create mode 100644 test/trans.d/case/scan2_julia.rl create mode 100644 test/trans.d/case/scan2_ocaml.rl create mode 100644 test/trans.d/case/scan2_ruby.rl create mode 100644 test/trans.d/case/scan2_rust.rl create mode 100644 test/trans.d/case/scan3.rl create mode 100644 test/trans.d/case/scan3_asm.rl create mode 100644 test/trans.d/case/scan3_c.rl create mode 100644 test/trans.d/case/scan3_crack.rl create mode 100644 test/trans.d/case/scan3_cs.rl create mode 100644 test/trans.d/case/scan3_d.rl create mode 100644 test/trans.d/case/scan3_go.rl create mode 100644 test/trans.d/case/scan3_java.rl create mode 100644 test/trans.d/case/scan3_julia.rl create mode 100644 test/trans.d/case/scan3_ocaml.rl create mode 100644 test/trans.d/case/scan3_ruby.rl create mode 100644 test/trans.d/case/scan3_rust.rl create mode 100644 test/trans.d/case/scan4.rl create mode 100644 test/trans.d/case/scan4_asm.rl create mode 100644 test/trans.d/case/scan4_c.rl create mode 100644 test/trans.d/case/scan4_crack.rl create mode 100644 test/trans.d/case/scan4_cs.rl create mode 100644 test/trans.d/case/scan4_d.rl create mode 100644 test/trans.d/case/scan4_go.rl create mode 100644 test/trans.d/case/scan4_java.rl create mode 100644 test/trans.d/case/scan4_julia.rl create mode 100644 test/trans.d/case/scan4_ocaml.rl create mode 100644 test/trans.d/case/scan4_ruby.rl create mode 100644 test/trans.d/case/scan4_rust.rl create mode 100644 test/trans.d/case/stateact1.rl create mode 100644 test/trans.d/case/stateact1_asm.rl create mode 100644 test/trans.d/case/stateact1_c.rl create mode 100644 test/trans.d/case/stateact1_crack.rl create mode 100644 test/trans.d/case/stateact1_cs.rl create mode 100644 test/trans.d/case/stateact1_d.rl create mode 100644 test/trans.d/case/stateact1_go.rl create mode 100644 test/trans.d/case/stateact1_java.rl create mode 100644 test/trans.d/case/stateact1_julia.rl create mode 100644 test/trans.d/case/stateact1_ocaml.rl create mode 100644 test/trans.d/case/stateact1_ruby.rl create mode 100644 test/trans.d/case/stateact1_rust.rl create mode 100644 test/trans.d/case/targs1.rl create mode 100644 test/trans.d/case/targs1_asm.rl create mode 100644 test/trans.d/case/targs1_c.rl create mode 100644 test/trans.d/case/targs1_crack.rl create mode 100644 test/trans.d/case/targs1_cs.rl create mode 100644 test/trans.d/case/targs1_d.rl create mode 100644 test/trans.d/case/targs1_go.rl create mode 100644 test/trans.d/case/targs1_java.rl create mode 100644 test/trans.d/case/targs1_julia.rl create mode 100644 test/trans.d/case/targs1_ocaml.rl create mode 100644 test/trans.d/case/targs1_ruby.rl create mode 100644 test/trans.d/case/targs1_rust.rl create mode 100644 test/trans.d/case/zlen1.rl create mode 100644 test/trans.d/case/zlen1_asm.rl create mode 100644 test/trans.d/case/zlen1_c.rl create mode 100644 test/trans.d/case/zlen1_crack.rl create mode 100644 test/trans.d/case/zlen1_cs.rl create mode 100644 test/trans.d/case/zlen1_d.rl create mode 100644 test/trans.d/case/zlen1_go.rl create mode 100644 test/trans.d/case/zlen1_java.rl create mode 100644 test/trans.d/case/zlen1_julia.rl create mode 100644 test/trans.d/case/zlen1_ocaml.rl create mode 100644 test/trans.d/case/zlen1_ruby.rl create mode 100644 test/trans.d/case/zlen1_rust.rl create mode 100755 test/trans.d/gentests create mode 100644 test/trans.d/main.c create mode 100644 test/trans.d/ragel-c.lm create mode 100644 test/trans.d/ragel-crack.lm create mode 100644 test/trans.d/ragel-ocaml.lm create mode 100644 test/trans.d/ragel-ruby.lm create mode 100644 test/trans.d/ragel.lm create mode 100644 test/trans.d/trans-asm.lm create mode 100644 test/trans.d/trans-c.lm create mode 100644 test/trans.d/trans-crack.lm create mode 100644 test/trans.d/trans-csharp.lm create mode 100644 test/trans.d/trans-d.lm create mode 100644 test/trans.d/trans-go.lm create mode 100644 test/trans.d/trans-java.lm create mode 100644 test/trans.d/trans-julia.lm create mode 100644 test/trans.d/trans-ocaml.lm create mode 100644 test/trans.d/trans-ruby.lm create mode 100644 test/trans.d/trans-rust.lm create mode 100644 test/trans.d/trans.lm (limited to 'test/trans.d') diff --git a/test/trans.d/.gitignore b/test/trans.d/.gitignore new file mode 100644 index 00000000..9dd4d30c --- /dev/null +++ b/test/trans.d/.gitignore @@ -0,0 +1,4 @@ +/trans +/trans.c +/*.o +/working diff --git a/test/trans.d/Makefile b/test/trans.d/Makefile new file mode 100644 index 00000000..b831cd2e --- /dev/null +++ b/test/trans.d/Makefile @@ -0,0 +1,30 @@ + +include ../colm.mk + +all: trans + +COLM = $(SUBJECT_BIN) +COLM_INC = $(SUBJECT_CPPFLAGS) +COLM_LIB = $(SUBJECT_LDFLAGS) + +TRANS_DEPS = $(wildcard *-*.lm) + +OBJ = actparams.o trans.o main.o + +trans: $(OBJ) + g++ -o $@ $(OBJ) $(COLM_LIB) -lcolm + +actparams.o: actparams.cc + g++ -c $(COLM_INC) -o $@ $< + +main.o: main.c + gcc -c $(COLM_INC) -o $@ $< + +trans.o: trans.c + gcc -c $(COLM_INC) -o $@ $< + +trans.c: trans.lm $(TRANS_DEPS) + $(COLM) -b trans_object -c -o $@ $< + +clean: + rm -f *.o diff --git a/test/trans.d/actparams.cc b/test/trans.d/actparams.cc new file mode 100644 index 00000000..d9e9d6ff --- /dev/null +++ b/test/trans.d/actparams.cc @@ -0,0 +1,63 @@ + +#include +#include + +#include +#include +#include + +using std::map; +using std::set; +using std::string; +using std::pair; +using std::cout; +using std::endl; + +extern "C" { + colm_value_t cc_action_params_find( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action ); + colm_value_t cc_action_params_insert( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action ); +} + +typedef set Set; +typedef map< string, Set > Map; +static Map machineMap; + +value_t cc_action_params_find( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action ) +{ + string machine( _machine->value->data, _machine->value->length ); + string action( _action->value->data, _action->value->length ); + + // cout << "cc_action_params_find " << machine << " " << action << " "; + + long res = 0; + Map::iterator M = machineMap.find( machine ); + if ( M != machineMap.end() ) + res = M->second.find( action ) != M->second.end(); + + // cout << ( res ? "FOUND" : "NOT FOUND" ) << endl; + + colm_tree_downref( prg, sp, (tree_t*)_machine ); + colm_tree_downref( prg, sp, (tree_t*)_action ); + + return (value_t) res; +} + +value_t cc_action_params_insert( struct colm_program *prg, tree_t **sp, str_t *_machine, str_t *_action ) +{ + string machine( _machine->value->data, _machine->value->length ); + string action( _action->value->data, _action->value->length ); + + // cout << "cc_action_params_insert " << machine << " " << action << endl; + + Map::iterator M = machineMap.find( machine ); + if ( M == machineMap.end() ) + machineMap.insert( pair( machine, Set() ) ); + + M = machineMap.find( machine ); + M->second.insert( action ); + + colm_tree_downref( prg, sp, (tree_t*)_machine ); + colm_tree_downref( prg, sp, (tree_t*)_action ); + + return 0; +} diff --git a/test/trans.d/case/any1.rl b/test/trans.d/case/any1.rl new file mode 100644 index 00000000..81ec713c --- /dev/null +++ b/test/trans.d/case/any1.rl @@ -0,0 +1,17 @@ +/* + * @LANG: indep + */ + +%%{ + machine any1; + main := any; +}%% + +##### INPUT ##### +"" +"x" +"xx" +##### OUTPUT ##### +FAIL +ACCEPT +FAIL diff --git a/test/trans.d/case/any1_asm.rl b/test/trans.d/case/any1_asm.rl new file mode 100644 index 00000000..4a9cc24e --- /dev/null +++ b/test/trans.d/case/any1_asm.rl @@ -0,0 +1,118 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine any1; + main := any; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq any1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "" +.L_inp_1: + .string "x" +.L_inp_2: + .string "xx" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + + .align 8 +inplen: + .quad 3 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/any1_c.rl b/test/trans.d/case/any1_c.rl new file mode 100644 index 00000000..6fbbb85c --- /dev/null +++ b/test/trans.d/case/any1_c.rl @@ -0,0 +1,62 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= any1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"", +"x", +"xx", +}; + +int inplen = 3; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/any1_crack.rl b/test/trans.d/case/any1_crack.rl new file mode 100644 index 00000000..8458ae75 --- /dev/null +++ b/test/trans.d/case/any1_crack.rl @@ -0,0 +1,47 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= any1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "" ); + m( "x" ); + m( "xx" ); +} + +main(); diff --git a/test/trans.d/case/any1_cs.rl b/test/trans.d/case/any1_cs.rl new file mode 100644 index 00000000..33700be9 --- /dev/null +++ b/test/trans.d/case/any1_cs.rl @@ -0,0 +1,67 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine any1; + main := any; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= any1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"", +"x", +"xx", +}; + + +static readonly int inplen = 3; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/any1_d.rl b/test/trans.d/case/any1_d.rl new file mode 100644 index 00000000..b08bb574 --- /dev/null +++ b/test/trans.d/case/any1_d.rl @@ -0,0 +1,66 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class any1 +{ + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= any1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"", +"x", +"xx", +]; + +int inplen = 3; + +} +int main() +{ + any1 m = new any1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/any1_go.rl b/test/trans.d/case/any1_go.rl new file mode 100644 index 00000000..71396428 --- /dev/null +++ b/test/trans.d/case/any1_go.rl @@ -0,0 +1,52 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine any1; + main := any; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= any1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"", +"x", +"xx", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/any1_java.rl b/test/trans.d/case/any1_java.rl new file mode 100644 index 00000000..ba28d77f --- /dev/null +++ b/test/trans.d/case/any1_java.rl @@ -0,0 +1,63 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class any1_java +{ + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= any1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"", +"x", +"xx", +}; + +static final int inplen = 3; + +public static void main (String[] args) +{ + any1_java machine = new any1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/any1_julia.rl b/test/trans.d/case/any1_julia.rl new file mode 100644 index 00000000..40b7387f --- /dev/null +++ b/test/trans.d/case/any1_julia.rl @@ -0,0 +1,37 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= any1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "" ); + m( "x" ); + m( "xx" ); diff --git a/test/trans.d/case/any1_ocaml.rl b/test/trans.d/case/any1_ocaml.rl new file mode 100644 index 00000000..d2bd7731 --- /dev/null +++ b/test/trans.d/case/any1_ocaml.rl @@ -0,0 +1,39 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine any1; + main := any; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= any1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec ""; + exec "x"; + exec "xx"; + () +;; + diff --git a/test/trans.d/case/any1_ruby.rl b/test/trans.d/case/any1_ruby.rl new file mode 100644 index 00000000..b102b035 --- /dev/null +++ b/test/trans.d/case/any1_ruby.rl @@ -0,0 +1,45 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= any1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"", +"x", +"xx", +] + +inplen = 3 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/any1_rust.rl b/test/trans.d/case/any1_rust.rl new file mode 100644 index 00000000..fc7939e2 --- /dev/null +++ b/test/trans.d/case/any1_rust.rl @@ -0,0 +1,44 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine any1; + main := any; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= any1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "".to_string() ); } + unsafe { m( "x".to_string() ); } + unsafe { m( "xx".to_string() ); } +} + diff --git a/test/trans.d/case/atoi1.rl b/test/trans.d/case/atoi1.rl new file mode 100644 index 00000000..b56996e5 --- /dev/null +++ b/test/trans.d/case/atoi1.rl @@ -0,0 +1,67 @@ +/* + * @LANG: indep + */ +bool neg; +int value; + +value = 0; +neg = false; +%%{ + machine atoi; + + action begin { + neg = false; + value = 0; + } + + action see_neg { + neg = true; + } + + action add_digit { + value = value * 10 + (fc - 48); + } + + action finish { + if ( neg != 0 ) { + value = -1 * value; + } + } + action print { + print_int value; + print_str "\n"; + } + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + +##### INPUT ##### +"1\n" +"12\n" +"222222\n" +"+2123\n" +"213 3213\n" +"-12321\n" +"--123\n" +"-99\n" +" -3000\n" +##### OUTPUT ##### +1 +ACCEPT +12 +ACCEPT +222222 +ACCEPT +2123 +ACCEPT +FAIL +-12321 +ACCEPT +FAIL +-99 +ACCEPT +FAIL diff --git a/test/trans.d/case/atoi1_asm.rl b/test/trans.d/case/atoi1_asm.rl new file mode 100644 index 00000000..085b5f37 --- /dev/null +++ b/test/trans.d/case/atoi1_asm.rl @@ -0,0 +1,246 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm neg,8,8 + .text + .section .data + .comm value,8,8 + .text + +%%{ + machine atoi; + + action begin { + movq $0, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + movq $0, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + +} + + action see_neg { + movq $1, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + +} + + action add_digit { + movq value (%rip), %rax + pushq %rax + movq $10 , %rax + pushq %rax + popq %rcx + popq %rax + imul %rcx, %rax + pushq %rax + movsbq (%r12), %rax + pushq %rax + movq $48, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + +} + + action finish { + movq neg (%rip), %rax + pushq %rax + movq $0 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setne %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 1f + movq $-1 , %rax + pushq %rax + movq value(%rip), %rax + pushq %rax + popq %rcx + popq %rax + imul %rcx, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) +1: + +} + action print { + movq value(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +3: + .string "\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + movq $0, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + movq $0, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq atoi_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1\n" +.L_inp_1: + .string "12\n" +.L_inp_2: + .string "222222\n" +.L_inp_3: + .string "+2123\n" +.L_inp_4: + .string "213 3213\n" +.L_inp_5: + .string "-12321\n" +.L_inp_6: + .string "--123\n" +.L_inp_7: + .string "-99\n" +.L_inp_8: + .string " -3000\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + + .align 8 +inplen: + .quad 9 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/atoi1_c.rl b/test/trans.d/case/atoi1_c.rl new file mode 100644 index 00000000..20409ccc --- /dev/null +++ b/test/trans.d/case/atoi1_c.rl @@ -0,0 +1,96 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int neg ; +int value ; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {printf( "%d", value ); +printf( "%s", "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= atoi_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +int inplen = 9; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/atoi1_crack.rl b/test/trans.d/case/atoi1_crack.rl new file mode 100644 index 00000000..8e3adfcc --- /dev/null +++ b/test/trans.d/case/atoi1_crack.rl @@ -0,0 +1,81 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int neg; +int value; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ( fc - 48 ) ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {cout.format( value ); +cout.format( "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= atoi_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1\n" ); + m( "12\n" ); + m( "222222\n" ); + m( "+2123\n" ); + m( "213 3213\n" ); + m( "-12321\n" ); + m( "--123\n" ); + m( "-99\n" ); + m( " -3000\n" ); +} + +main(); diff --git a/test/trans.d/case/atoi1_cs.rl b/test/trans.d/case/atoi1_cs.rl new file mode 100644 index 00000000..64051f10 --- /dev/null +++ b/test/trans.d/case/atoi1_cs.rl @@ -0,0 +1,99 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int neg; +int value; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {Console.Write( value );Console.Write( "\n" );} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + +%% write data; +int cs; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= atoi_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + + +static readonly int inplen = 9; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/atoi1_d.rl b/test/trans.d/case/atoi1_d.rl new file mode 100644 index 00000000..1d9d0ffa --- /dev/null +++ b/test/trans.d/case/atoi1_d.rl @@ -0,0 +1,99 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class atoi +{ +int neg; +int value; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + cast( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {printf( "%d", value ); +printf( "%.*s", "\n" );} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= atoi_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +]; + +int inplen = 9; + +} +int main() +{ + atoi m = new atoi(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/atoi1_go.rl b/test/trans.d/case/atoi1_go.rl new file mode 100644 index 00000000..0ffa7a1a --- /dev/null +++ b/test/trans.d/case/atoi1_go.rl @@ -0,0 +1,83 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var neg int ; +var value int ; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) { + value = -1 * value; + +} +} + action print {fmt.Print( value );fmt.Print( "\n" );} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { +value = 0; +neg = 0; + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= atoi_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/atoi1_java.rl b/test/trans.d/case/atoi1_java.rl new file mode 100644 index 00000000..033555d1 --- /dev/null +++ b/test/trans.d/case/atoi1_java.rl @@ -0,0 +1,97 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class atoi1_java +{ +int neg ; +int value ; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {System.out.print( value ); +System.out.print( "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; +int cs; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= atoi_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +static final int inplen = 9; + +public static void main (String[] args) +{ + atoi1_java machine = new atoi1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/atoi1_julia.rl b/test/trans.d/case/atoi1_julia.rl new file mode 100644 index 00000000..1576981f --- /dev/null +++ b/test/trans.d/case/atoi1_julia.rl @@ -0,0 +1,70 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + convert( Int, ( fc - 48 ) ) +; +} + + action finish {if ( neg != 0 ) + value = -1 * value; + +end +} + action print {print( value ); +print( "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +neg = 0; +value = 0; +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= atoi_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1\n" ); + m( "12\n" ); + m( "222222\n" ); + m( "+2123\n" ); + m( "213 3213\n" ); + m( "-12321\n" ); + m( "--123\n" ); + m( "-99\n" ); + m( " -3000\n" ); diff --git a/test/trans.d/case/atoi1_ocaml.rl b/test/trans.d/case/atoi1_ocaml.rl new file mode 100644 index 00000000..b0bc8c9f --- /dev/null +++ b/test/trans.d/case/atoi1_ocaml.rl @@ -0,0 +1,74 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let neg = ref 0 +let value = ref 0 + +%%{ + machine atoi; + + action begin {neg := 0; +value := 0; +} + + action see_neg {neg := 1; +} + + action add_digit {value := value .contents * 10 + ( fc - 48 ) +; +} + + action finish {if neg .contents != 0 then +begin + value := -1 * value.contents; + +end +; +} + action print {print_int( value.contents ); +print_string( "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in +value := 0; +neg := 0; + %% write init; + %% write exec; + if !cs >= atoi_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1\n"; + exec "12\n"; + exec "222222\n"; + exec "+2123\n"; + exec "213 3213\n"; + exec "-12321\n"; + exec "--123\n"; + exec "-99\n"; + exec " -3000\n"; + () +;; + diff --git a/test/trans.d/case/atoi1_ruby.rl b/test/trans.d/case/atoi1_ruby.rl new file mode 100644 index 00000000..c8a67ccc --- /dev/null +++ b/test/trans.d/case/atoi1_ruby.rl @@ -0,0 +1,78 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) + value = -1 * value; + +end +} + action print {print( value ); +print( "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +neg = 1 +value = 1 +value = 0; +neg = 0; + %% write init; + %% write exec; + if cs >= atoi_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +] + +inplen = 9 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/atoi1_rust.rl b/test/trans.d/case/atoi1_rust.rl new file mode 100644 index 00000000..3af63b7f --- /dev/null +++ b/test/trans.d/case/atoi1_rust.rl @@ -0,0 +1,78 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut neg : i8 = 0; +static mut value : i32 = 0; + +%%{ + machine atoi; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( ( fc - 48 ) as i32 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + action print {print!( "{}", value ); +print!( "{}", "\n" ); +} + + atoi = ( + ('-'@see_neg | '+')? (digit @add_digit)+ + ) >begin %finish; + + main := atoi '\n' @print; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= atoi_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1\n".to_string() ); } + unsafe { m( "12\n".to_string() ); } + unsafe { m( "222222\n".to_string() ); } + unsafe { m( "+2123\n".to_string() ); } + unsafe { m( "213 3213\n".to_string() ); } + unsafe { m( "-12321\n".to_string() ); } + unsafe { m( "--123\n".to_string() ); } + unsafe { m( "-99\n".to_string() ); } + unsafe { m( " -3000\n".to_string() ); } +} + diff --git a/test/trans.d/case/atoi2.rl b/test/trans.d/case/atoi2.rl new file mode 100644 index 00000000..9b8cd13c --- /dev/null +++ b/test/trans.d/case/atoi2.rl @@ -0,0 +1,81 @@ +/* + * @LANG: indep + * This implementes an atoi machine using the statechart paradigm. + */ +bool neg; +int value; + +value = 0; +neg = false; + +%%{ + machine state_chart; + + action begin { + neg = false; + value = 0; + } + + action see_neg { + neg = true; + } + + action add_digit { + value = value * 10 + (fc - 48); + } + + action finish { + if ( neg != 0 ) { + value = -1 * value; + } + } + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof { print_int value; print_str "\n"; } + main := ( atoi '\n' @oneof )*; +}%% + +##### INPUT ##### +"1\n" +"12\n" +"222222\n" +"+2123\n" +"213 3213\n" +"-12321\n" +"--123\n" +"-99\n" +" -3000\n" +##### OUTPUT ##### +1 +ACCEPT +12 +ACCEPT +222222 +ACCEPT +2123 +ACCEPT +FAIL +-12321 +ACCEPT +FAIL +-99 +ACCEPT +FAIL diff --git a/test/trans.d/case/atoi2_asm.rl b/test/trans.d/case/atoi2_asm.rl new file mode 100644 index 00000000..51e8eb48 --- /dev/null +++ b/test/trans.d/case/atoi2_asm.rl @@ -0,0 +1,261 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm neg,8,8 + .text + .section .data + .comm value,8,8 + .text + +%%{ + machine state_chart; + + action begin { + movq $0, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + movq $0, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + +} + + action see_neg { + movq $1, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + +} + + action add_digit { + movq value (%rip), %rax + pushq %rax + movq $10 , %rax + pushq %rax + popq %rcx + popq %rax + imul %rcx, %rax + pushq %rax + movsbq (%r12), %rax + pushq %rax + movq $48, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + +} + + action finish { + movq neg (%rip), %rax + pushq %rax + movq $0 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setne %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 1f + movq $-1 , %rax + pushq %rax + movq value(%rip), %rax + pushq %rax + popq %rcx + popq %rax + imul %rcx, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) +1: + +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof { + movq value(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +3: + .string "\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + main := ( atoi '\n' @oneof )*; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + movq $0, %rax + pushq %rax + popq %rax + movq %rax, value (%rip) + movq $0, %rax + pushq %rax + popq %rax + movq %rax, neg (%rip) + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq state_chart_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1\n" +.L_inp_1: + .string "12\n" +.L_inp_2: + .string "222222\n" +.L_inp_3: + .string "+2123\n" +.L_inp_4: + .string "213 3213\n" +.L_inp_5: + .string "-12321\n" +.L_inp_6: + .string "--123\n" +.L_inp_7: + .string "-99\n" +.L_inp_8: + .string " -3000\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + + .align 8 +inplen: + .quad 9 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/atoi2_c.rl b/test/trans.d/case/atoi2_c.rl new file mode 100644 index 00000000..0a7431fe --- /dev/null +++ b/test/trans.d/case/atoi2_c.rl @@ -0,0 +1,111 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int neg ; +int value ; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {printf( "%d", value ); +printf( "%s", "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_chart_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +int inplen = 9; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/atoi2_crack.rl b/test/trans.d/case/atoi2_crack.rl new file mode 100644 index 00000000..cf7123cf --- /dev/null +++ b/test/trans.d/case/atoi2_crack.rl @@ -0,0 +1,96 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int neg; +int value; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ( fc - 48 ) ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {cout.format( value ); +cout.format( "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= state_chart_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1\n" ); + m( "12\n" ); + m( "222222\n" ); + m( "+2123\n" ); + m( "213 3213\n" ); + m( "-12321\n" ); + m( "--123\n" ); + m( "-99\n" ); + m( " -3000\n" ); +} + +main(); diff --git a/test/trans.d/case/atoi2_cs.rl b/test/trans.d/case/atoi2_cs.rl new file mode 100644 index 00000000..b3a182b8 --- /dev/null +++ b/test/trans.d/case/atoi2_cs.rl @@ -0,0 +1,114 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int neg; +int value; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {Console.Write( value );Console.Write( "\n" );} + main := ( atoi '\n' @oneof )*; +}%% + + +%% write data; +int cs; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_chart_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + + +static readonly int inplen = 9; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/atoi2_d.rl b/test/trans.d/case/atoi2_d.rl new file mode 100644 index 00000000..301cf6fa --- /dev/null +++ b/test/trans.d/case/atoi2_d.rl @@ -0,0 +1,114 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class state_chart +{ +int neg; +int value; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + cast( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {printf( "%d", value ); +printf( "%.*s", "\n" );} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_chart_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +]; + +int inplen = 9; + +} +int main() +{ + state_chart m = new state_chart(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/atoi2_go.rl b/test/trans.d/case/atoi2_go.rl new file mode 100644 index 00000000..4ff0d8d9 --- /dev/null +++ b/test/trans.d/case/atoi2_go.rl @@ -0,0 +1,98 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var neg int ; +var value int ; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) { + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {fmt.Print( value );fmt.Print( "\n" );} + main := ( atoi '\n' @oneof )*; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { +value = 0; +neg = 0; + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= state_chart_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/atoi2_java.rl b/test/trans.d/case/atoi2_java.rl new file mode 100644 index 00000000..e26228e3 --- /dev/null +++ b/test/trans.d/case/atoi2_java.rl @@ -0,0 +1,112 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class atoi2_java +{ +int neg ; +int value ; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( int ) ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {System.out.print( value ); +System.out.print( "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; +int cs; + +void init() +{ +value = 0; +neg = 0; + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_chart_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +}; + +static final int inplen = 9; + +public static void main (String[] args) +{ + atoi2_java machine = new atoi2_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/atoi2_julia.rl b/test/trans.d/case/atoi2_julia.rl new file mode 100644 index 00000000..b43e2593 --- /dev/null +++ b/test/trans.d/case/atoi2_julia.rl @@ -0,0 +1,85 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + convert( Int, ( fc - 48 ) ) +; +} + + action finish {if ( neg != 0 ) + value = -1 * value; + +end +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {print( value ); +print( "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +neg = 0; +value = 0; +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= state_chart_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1\n" ); + m( "12\n" ); + m( "222222\n" ); + m( "+2123\n" ); + m( "213 3213\n" ); + m( "-12321\n" ); + m( "--123\n" ); + m( "-99\n" ); + m( " -3000\n" ); diff --git a/test/trans.d/case/atoi2_ocaml.rl b/test/trans.d/case/atoi2_ocaml.rl new file mode 100644 index 00000000..45dc1f6e --- /dev/null +++ b/test/trans.d/case/atoi2_ocaml.rl @@ -0,0 +1,89 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let neg = ref 0 +let value = ref 0 + +%%{ + machine state_chart; + + action begin {neg := 0; +value := 0; +} + + action see_neg {neg := 1; +} + + action add_digit {value := value .contents * 10 + ( fc - 48 ) +; +} + + action finish {if neg .contents != 0 then +begin + value := -1 * value.contents; + +end +; +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {print_int( value.contents ); +print_string( "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in +value := 0; +neg := 0; + %% write init; + %% write exec; + if !cs >= state_chart_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1\n"; + exec "12\n"; + exec "222222\n"; + exec "+2123\n"; + exec "213 3213\n"; + exec "-12321\n"; + exec "--123\n"; + exec "-99\n"; + exec " -3000\n"; + () +;; + diff --git a/test/trans.d/case/atoi2_ruby.rl b/test/trans.d/case/atoi2_ruby.rl new file mode 100644 index 00000000..0d86d793 --- /dev/null +++ b/test/trans.d/case/atoi2_ruby.rl @@ -0,0 +1,93 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( fc - 48 ) +; +} + + action finish {if ( neg != 0 ) + value = -1 * value; + +end +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {print( value ); +print( "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +neg = 1 +value = 1 +value = 0; +neg = 0; + %% write init; + %% write exec; + if cs >= state_chart_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1\n", +"12\n", +"222222\n", +"+2123\n", +"213 3213\n", +"-12321\n", +"--123\n", +"-99\n", +" -3000\n", +] + +inplen = 9 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/atoi2_rust.rl b/test/trans.d/case/atoi2_rust.rl new file mode 100644 index 00000000..5510068a --- /dev/null +++ b/test/trans.d/case/atoi2_rust.rl @@ -0,0 +1,93 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut neg : i8 = 0; +static mut value : i32 = 0; + +%%{ + machine state_chart; + + action begin {neg = 0; +value = 0; +} + + action see_neg {neg = 1; +} + + action add_digit {value = value * 10 + ( ( fc - 48 ) as i32 ) +; +} + + action finish {if ( neg != 0 ) +{ + value = -1 * value; + +} +} + + atoi = ( + start: ( + '-' @see_neg ->om_num | + '+' ->om_num | + [0-9] @add_digit ->more_nums + ), + + # One or more nums. + om_num: ( + [0-9] @add_digit ->more_nums + ), + + # Zero ore more nums. + more_nums: ( + [0-9] @add_digit ->more_nums | + '' -> final + ) + ) >begin %finish; + + action oneof {print!( "{}", value ); +print!( "{}", "\n" ); +} + main := ( atoi '\n' @oneof )*; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); +value = 0; +neg = 0; + + %% write init; + %% write exec; + + if ( cs >= state_chart_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1\n".to_string() ); } + unsafe { m( "12\n".to_string() ); } + unsafe { m( "222222\n".to_string() ); } + unsafe { m( "+2123\n".to_string() ); } + unsafe { m( "213 3213\n".to_string() ); } + unsafe { m( "-12321\n".to_string() ); } + unsafe { m( "--123\n".to_string() ); } + unsafe { m( "-99\n".to_string() ); } + unsafe { m( " -3000\n".to_string() ); } +} + diff --git a/test/trans.d/case/call4.rl b/test/trans.d/case/call4.rl new file mode 100644 index 00000000..72edf30e --- /dev/null +++ b/test/trans.d/case/call4.rl @@ -0,0 +1,39 @@ +/* + * @LANG: indep + * @PROHIBIT_LANGUAGES: ruby ocaml + * @PROHIBIT_FEATFLAGS: --var-backend + */ + +int target; +int top; +int stack[32]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + fret; + }; + + two := 'two' @{ + print_str "two\n"; + fret; + }; + + main := ( + '1' @{ target = fentry(one); fcall *target; } + | '2' @{ target = fentry(two); fcall *target; } + | '\n' + )*; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/call4_asm.rl b/test/trans.d/case/call4_asm.rl new file mode 100644 index 00000000..70e816ed --- /dev/null +++ b/test/trans.d/case/call4_asm.rl @@ -0,0 +1,180 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm target,8,8 + .text + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fret; + + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fret; + + +}; + + main := ( + '1' @{ + movq $fentry(one), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +} + | '2' @{ + movq $fentry(two), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +} + | '\n' + )*; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq call4_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/call4_c.rl b/test/trans.d/case/call4_c.rl new file mode 100644 index 00000000..e8002904 --- /dev/null +++ b/test/trans.d/case/call4_c.rl @@ -0,0 +1,76 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int target ; +int top ; +int stack [32]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +fret;}; + + two := 'two' @{printf( "%s", "two\n" ); +fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= call4_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/call4_crack.rl b/test/trans.d/case/call4_crack.rl new file mode 100644 index 00000000..ecac128b --- /dev/null +++ b/test/trans.d/case/call4_crack.rl @@ -0,0 +1,61 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int target; +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +fret;}; + + two := 'two' @{cout.format( "two\n" ); +fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= call4_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/call4_cs.rl b/test/trans.d/case/call4_cs.rl new file mode 100644 index 00000000..19f01958 --- /dev/null +++ b/test/trans.d/case/call4_cs.rl @@ -0,0 +1,79 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int target; +int top; +int [] stack = new int [32]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );fret;}; + + two := 'two' @{Console.Write( "two\n" );fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= call4_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/call4_d.rl b/test/trans.d/case/call4_d.rl new file mode 100644 index 00000000..b187ce85 --- /dev/null +++ b/test/trans.d/case/call4_d.rl @@ -0,0 +1,78 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class call4 +{ +int target; +int top; +int stack[32]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );fret;}; + + two := 'two' @{printf( "%.*s", "two\n" );fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= call4_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + call4 m = new call4(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/call4_go.rl b/test/trans.d/case/call4_go.rl new file mode 100644 index 00000000..886f3031 --- /dev/null +++ b/test/trans.d/case/call4_go.rl @@ -0,0 +1,70 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var target int ; +var top int ; +var stack [32] int ; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );fret; + +}; + + two := 'two' @{fmt.Print( "two\n" );fret; + +}; + + main := ( + '1' @{target = fentry(one); +fcall *target; +} + | '2' @{target = fentry(two); +fcall *target; +} + | '\n' + )*; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= call4_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/call4_java.rl b/test/trans.d/case/call4_java.rl new file mode 100644 index 00000000..5bdf9a3f --- /dev/null +++ b/test/trans.d/case/call4_java.rl @@ -0,0 +1,77 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class call4_java +{ +int target ; +int top ; +int stack [] = new int[32]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +fret;}; + + two := 'two' @{System.out.print( "two\n" ); +fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= call4_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + call4_java machine = new call4_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/call4_julia.rl b/test/trans.d/case/call4_julia.rl new file mode 100644 index 00000000..263e65d6 --- /dev/null +++ b/test/trans.d/case/call4_julia.rl @@ -0,0 +1,51 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fret;}; + + two := 'two' @{print( "two\n" ); +fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +target = 0; +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + %% write init; + %% write exec; + + if ( cs >= call4_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/call4_rust.rl b/test/trans.d/case/call4_rust.rl new file mode 100644 index 00000000..f9d24550 --- /dev/null +++ b/test/trans.d/case/call4_rust.rl @@ -0,0 +1,58 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut target : i32 = 0; +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine call4; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +fret;}; + + two := 'two' @{print!( "{}", "two\n" ); +fret;}; + + main := ( + '1' @{target = fentry(one); +fcall *target;} + | '2' @{target = fentry(two); +fcall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= call4_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/caseindep.rl b/test/trans.d/case/caseindep.rl new file mode 100644 index 00000000..d3bd188c --- /dev/null +++ b/test/trans.d/case/caseindep.rl @@ -0,0 +1,54 @@ +/* + * @LANG: indep + */ +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + +##### INPUT ##### +"1hello\n" +"1HELLO\n" +"1HeLLo\n" +"2hello\n" +"2HELLO\n" +"2HeLLo\n" +"3hello\n" +"3HELLO\n" +"3HeLLo\n" +"4hello\n" +"4HELLO\n" +"4HeLLo\n" +"5hello\n" +"5HELLO\n" +"5HeLLo\n" +"6hello\n" +"6HELLO\n" +"6HeLLo\n" +##### OUTPUT ##### +ACCEPT +FAIL +FAIL +ACCEPT +FAIL +FAIL +ACCEPT +FAIL +FAIL +ACCEPT +ACCEPT +ACCEPT +ACCEPT +ACCEPT +ACCEPT +ACCEPT +ACCEPT +ACCEPT diff --git a/test/trans.d/case/caseindep_asm.rl b/test/trans.d/case/caseindep_asm.rl new file mode 100644 index 00000000..bc4aca8f --- /dev/null +++ b/test/trans.d/case/caseindep_asm.rl @@ -0,0 +1,170 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq indep_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1hello\n" +.L_inp_1: + .string "1HELLO\n" +.L_inp_2: + .string "1HeLLo\n" +.L_inp_3: + .string "2hello\n" +.L_inp_4: + .string "2HELLO\n" +.L_inp_5: + .string "2HeLLo\n" +.L_inp_6: + .string "3hello\n" +.L_inp_7: + .string "3HELLO\n" +.L_inp_8: + .string "3HeLLo\n" +.L_inp_9: + .string "4hello\n" +.L_inp_10: + .string "4HELLO\n" +.L_inp_11: + .string "4HeLLo\n" +.L_inp_12: + .string "5hello\n" +.L_inp_13: + .string "5HELLO\n" +.L_inp_14: + .string "5HeLLo\n" +.L_inp_15: + .string "6hello\n" +.L_inp_16: + .string "6HELLO\n" +.L_inp_17: + .string "6HeLLo\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + .quad .L_inp_9 + .quad .L_inp_10 + .quad .L_inp_11 + .quad .L_inp_12 + .quad .L_inp_13 + .quad .L_inp_14 + .quad .L_inp_15 + .quad .L_inp_16 + .quad .L_inp_17 + + .align 8 +inplen: + .quad 18 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/caseindep_c.rl b/test/trans.d/case/caseindep_c.rl new file mode 100644 index 00000000..a0771ae0 --- /dev/null +++ b/test/trans.d/case/caseindep_c.rl @@ -0,0 +1,84 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= indep_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +}; + +int inplen = 18; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/caseindep_crack.rl b/test/trans.d/case/caseindep_crack.rl new file mode 100644 index 00000000..a4c2bf8a --- /dev/null +++ b/test/trans.d/case/caseindep_crack.rl @@ -0,0 +1,69 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= indep_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1hello\n" ); + m( "1HELLO\n" ); + m( "1HeLLo\n" ); + m( "2hello\n" ); + m( "2HELLO\n" ); + m( "2HeLLo\n" ); + m( "3hello\n" ); + m( "3HELLO\n" ); + m( "3HeLLo\n" ); + m( "4hello\n" ); + m( "4HELLO\n" ); + m( "4HeLLo\n" ); + m( "5hello\n" ); + m( "5HELLO\n" ); + m( "5HeLLo\n" ); + m( "6hello\n" ); + m( "6HELLO\n" ); + m( "6HeLLo\n" ); +} + +main(); diff --git a/test/trans.d/case/caseindep_cs.rl b/test/trans.d/case/caseindep_cs.rl new file mode 100644 index 00000000..404be8f1 --- /dev/null +++ b/test/trans.d/case/caseindep_cs.rl @@ -0,0 +1,89 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= indep_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +}; + + +static readonly int inplen = 18; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/caseindep_d.rl b/test/trans.d/case/caseindep_d.rl new file mode 100644 index 00000000..dc666dd9 --- /dev/null +++ b/test/trans.d/case/caseindep_d.rl @@ -0,0 +1,88 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class indep +{ + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= indep_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +]; + +int inplen = 18; + +} +int main() +{ + indep m = new indep(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/caseindep_go.rl b/test/trans.d/case/caseindep_go.rl new file mode 100644 index 00000000..106751a8 --- /dev/null +++ b/test/trans.d/case/caseindep_go.rl @@ -0,0 +1,74 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= indep_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/caseindep_java.rl b/test/trans.d/case/caseindep_java.rl new file mode 100644 index 00000000..2156fe34 --- /dev/null +++ b/test/trans.d/case/caseindep_java.rl @@ -0,0 +1,85 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class caseindep_java +{ + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= indep_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +}; + +static final int inplen = 18; + +public static void main (String[] args) +{ + caseindep_java machine = new caseindep_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/caseindep_julia.rl b/test/trans.d/case/caseindep_julia.rl new file mode 100644 index 00000000..9a39658a --- /dev/null +++ b/test/trans.d/case/caseindep_julia.rl @@ -0,0 +1,59 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= indep_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1hello\n" ); + m( "1HELLO\n" ); + m( "1HeLLo\n" ); + m( "2hello\n" ); + m( "2HELLO\n" ); + m( "2HeLLo\n" ); + m( "3hello\n" ); + m( "3HELLO\n" ); + m( "3HeLLo\n" ); + m( "4hello\n" ); + m( "4HELLO\n" ); + m( "4HeLLo\n" ); + m( "5hello\n" ); + m( "5HELLO\n" ); + m( "5HeLLo\n" ); + m( "6hello\n" ); + m( "6HELLO\n" ); + m( "6HeLLo\n" ); diff --git a/test/trans.d/case/caseindep_ocaml.rl b/test/trans.d/case/caseindep_ocaml.rl new file mode 100644 index 00000000..90aedfc4 --- /dev/null +++ b/test/trans.d/case/caseindep_ocaml.rl @@ -0,0 +1,61 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= indep_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1hello\n"; + exec "1HELLO\n"; + exec "1HeLLo\n"; + exec "2hello\n"; + exec "2HELLO\n"; + exec "2HeLLo\n"; + exec "3hello\n"; + exec "3HELLO\n"; + exec "3HeLLo\n"; + exec "4hello\n"; + exec "4HELLO\n"; + exec "4HeLLo\n"; + exec "5hello\n"; + exec "5HELLO\n"; + exec "5HeLLo\n"; + exec "6hello\n"; + exec "6HELLO\n"; + exec "6HeLLo\n"; + () +;; + diff --git a/test/trans.d/case/caseindep_ruby.rl b/test/trans.d/case/caseindep_ruby.rl new file mode 100644 index 00000000..3d21d0c9 --- /dev/null +++ b/test/trans.d/case/caseindep_ruby.rl @@ -0,0 +1,67 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= indep_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1hello\n", +"1HELLO\n", +"1HeLLo\n", +"2hello\n", +"2HELLO\n", +"2HeLLo\n", +"3hello\n", +"3HELLO\n", +"3HeLLo\n", +"4hello\n", +"4HELLO\n", +"4HeLLo\n", +"5hello\n", +"5HELLO\n", +"5HeLLo\n", +"6hello\n", +"6HELLO\n", +"6HeLLo\n", +] + +inplen = 18 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/caseindep_rust.rl b/test/trans.d/case/caseindep_rust.rl new file mode 100644 index 00000000..281a9af5 --- /dev/null +++ b/test/trans.d/case/caseindep_rust.rl @@ -0,0 +1,66 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + +%%{ + machine indep; + + main := ( + ( '1' 'hello' ) | + ( '2' "hello" ) | + ( '3' /hello/ ) | + ( '4' 'hello'i ) | + ( '5' "hello"i ) | + ( '6' /hello/i ) + ) '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= indep_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1hello\n".to_string() ); } + unsafe { m( "1HELLO\n".to_string() ); } + unsafe { m( "1HeLLo\n".to_string() ); } + unsafe { m( "2hello\n".to_string() ); } + unsafe { m( "2HELLO\n".to_string() ); } + unsafe { m( "2HeLLo\n".to_string() ); } + unsafe { m( "3hello\n".to_string() ); } + unsafe { m( "3HELLO\n".to_string() ); } + unsafe { m( "3HeLLo\n".to_string() ); } + unsafe { m( "4hello\n".to_string() ); } + unsafe { m( "4HELLO\n".to_string() ); } + unsafe { m( "4HeLLo\n".to_string() ); } + unsafe { m( "5hello\n".to_string() ); } + unsafe { m( "5HELLO\n".to_string() ); } + unsafe { m( "5HeLLo\n".to_string() ); } + unsafe { m( "6hello\n".to_string() ); } + unsafe { m( "6HELLO\n".to_string() ); } + unsafe { m( "6HeLLo\n".to_string() ); } +} + diff --git a/test/trans.d/case/clang4.rl b/test/trans.d/case/clang4.rl new file mode 100644 index 00000000..b033a479 --- /dev/null +++ b/test/trans.d/case/clang4.rl @@ -0,0 +1,187 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +int pos; +int line; + +pos = 0; +line = 1; +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buf_append(); } + + # Function to clear the buffer. + action clearBuf { buf_clear(); } + + action incLine { line = line + 1; } + + # Functions to dump tokens as they are matched. + action ident { + print_str "ident("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + action literal { + print_str "literal("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + action float { + print_str "float("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + action integer { + print_str "int("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + action hex { + print_str "hex("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + action symbol { + print_str "symbol("; + print_int line; + print_str ","; + print_int blen; + print_str "): "; + print_str buffer; + print_str "\n"; + } + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + +##### INPUT ##### +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" +##### OUTPUT ##### +int(1,3): 999 +hex(1,6): aAFF99 +float(1,5): 99.99 +literal(2,5): lksdj +literal(8,12): + +literal + + + +hex(8,5): 00aba +ident(8,8): foobardd +symbol(8,1): . +ident(8,4): ddsf +hex(8,1): 0 +symbol(8,1): . +int(8,1): 9 +ACCEPT +ident(1,17): wordwithnum00asdf +int(2,3): 000 +ident(2,14): wordfollowsnum +symbol(2,1): , +ident(2,5): makes +ident(2,3): new +ident(2,6): symbol +ident(4,9): finishing +ident(4,5): early +FAIL diff --git a/test/trans.d/case/clang4_asm.rl b/test/trans.d/case/clang4_asm.rl new file mode 100644 index 00000000..882cd148 --- /dev/null +++ b/test/trans.d/case/clang4_asm.rl @@ -0,0 +1,603 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm pos,8,8 + .text + .section .data + .comm line,8,8 + .text + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { + movq bpos(%rip), %rax + movb (%r12), %cl + movb %cl, buf(%rax) + addq $1, %rax + movb $0, buf(%rax) + movq %rax, bpos(%rip) + +} + + # Function to clear the buffer. + action clearBuf { + movq $0, bpos(%rip) + +} + + action incLine { + movq line (%rip), %rax + pushq %rax + movq $1, %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + popq %rax + movq %rax, line (%rip) + +} + + # Functions to dump tokens as they are matched. + action ident { + .section .rodata +1: + .string "ident(" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +2: + .string "," + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +3: + .string "): " + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +4: + .string "\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action literal { + .section .rodata +5: + .string "literal(" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +6: + .string "," + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +7: + .string "): " + .text + movq $7b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +8: + .string "\n" + .text + movq $8b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action float { + .section .rodata +9: + .string "float(" + .text + movq $9b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +10: + .string "," + .text + movq $10b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +11: + .string "): " + .text + movq $11b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +12: + .string "\n" + .text + movq $12b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action integer { + .section .rodata +13: + .string "int(" + .text + movq $13b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +14: + .string "," + .text + movq $14b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +15: + .string "): " + .text + movq $15b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +16: + .string "\n" + .text + movq $16b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action hex { + .section .rodata +17: + .string "hex(" + .text + movq $17b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +18: + .string "," + .text + movq $18b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +19: + .string "): " + .text + movq $19b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +20: + .string "\n" + .text + movq $20b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action symbol { + .section .rodata +21: + .string "symbol(" + .text + movq $21b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq line(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +22: + .string "," + .text + movq $22b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq bpos(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +23: + .string "): " + .text + movq $23b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $buf, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +24: + .string "\n" + .text + movq $24b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + movq $0, %rax + pushq %rax + popq %rax + movq %rax, pos (%rip) + movq $1, %rax + pushq %rax + popq %rax + movq %rax, line (%rip) + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq clang_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" +.L_inp_1: + .string "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + + .align 8 +inplen: + .quad 2 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/clang4_c.rl b/test/trans.d/case/clang4_c.rl new file mode 100644 index 00000000..b64d027a --- /dev/null +++ b/test/trans.d/case/clang4_c.rl @@ -0,0 +1,202 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int pos ; +int line ; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen++] = *p; + buffer[blen] = 0; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {printf( "%s", "ident(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + action literal {printf( "%s", "literal(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + action float {printf( "%s", "float(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + action integer {printf( "%s", "int(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + action hex {printf( "%s", "hex(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + action symbol {printf( "%s", "symbol(" ); +printf( "%d", line ); +printf( "%s", "," ); +printf( "%d", blen ); +printf( "%s", "): " ); +printf( "%s", buffer ); +printf( "%s", "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +pos = 0; +line = 1; + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= clang_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +}; + +int inplen = 2; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/clang4_crack.rl b/test/trans.d/case/clang4_crack.rl new file mode 100644 index 00000000..c15c5c60 --- /dev/null +++ b/test/trans.d/case/clang4_crack.rl @@ -0,0 +1,186 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int pos; +int line; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer = buffer + fc; +} + + # Function to clear the buffer. + action clearBuf { buffer = ""; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {cout.format( "ident(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + action literal {cout.format( "literal(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + action float {cout.format( "float(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + action integer {cout.format( "int(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + action hex {cout.format( "hex(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + action symbol {cout.format( "symbol(" ); +cout.format( line ); +cout.format( "," ); +cout.format( buffer.size ); +cout.format( "): " ); +cout.format( buffer ); +cout.format( "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; +pos = 0; +line = 1; + + %% write init; + %% write exec; + + if ( cs >= clang_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" ); + m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" ); +} + +main(); diff --git a/test/trans.d/case/clang4_cs.rl b/test/trans.d/case/clang4_cs.rl new file mode 100644 index 00000000..19bcdc9a --- /dev/null +++ b/test/trans.d/case/clang4_cs.rl @@ -0,0 +1,169 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int pos; +int line; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen++] = fc; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {Console.Write( "ident(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + action literal {Console.Write( "literal(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + action float {Console.Write( "float(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + action integer {Console.Write( "int(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + action hex {Console.Write( "hex(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + action symbol {Console.Write( "symbol(" );Console.Write( line );Console.Write( "," );Console.Write( blen );Console.Write( "): " );Console.Write( new String( buffer, 0, blen ) + );Console.Write( "\n" );} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + +%% write data; +int cs; + +void init() +{ +pos = 0; +line = 1; + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= clang_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +}; + + +static readonly int inplen = 2; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/clang4_d.rl b/test/trans.d/case/clang4_d.rl new file mode 100644 index 00000000..3c890ca3 --- /dev/null +++ b/test/trans.d/case/clang4_d.rl @@ -0,0 +1,176 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class clang +{ +int pos; +int line; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen++] = *p; + buffer[blen] = 0; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {printf( "%.*s", "ident(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + action literal {printf( "%.*s", "literal(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + action float {printf( "%.*s", "float(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + action integer {printf( "%.*s", "int(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + action hex {printf( "%.*s", "hex(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + action symbol {printf( "%.*s", "symbol(" );printf( "%d", line ); +printf( "%.*s", "," );printf( "%d", blen ); +printf( "%.*s", "): " );printf( "%.*s", buffer );printf( "%.*s", "\n" );} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ +pos = 0; +line = 1; + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= clang_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +]; + +int inplen = 2; + +} +int main() +{ + clang m = new clang(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/clang4_go.rl b/test/trans.d/case/clang4_go.rl new file mode 100644 index 00000000..bbdd169e --- /dev/null +++ b/test/trans.d/case/clang4_go.rl @@ -0,0 +1,151 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var pos int ; +var line int ; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen] = fc; + blen += 1; + buffer[blen] = 0; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {fmt.Print( "ident(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + action literal {fmt.Print( "literal(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + action float {fmt.Print( "float(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + action integer {fmt.Print( "int(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + action hex {fmt.Print( "hex(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + action symbol {fmt.Print( "symbol(" );fmt.Print( line );fmt.Print( "," );fmt.Print( blen );fmt.Print( "): " );fmt.Print( string ( buffer[:blen] ) );fmt.Print( "\n" );} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { +pos = 0; +line = 1; + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= clang_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/clang4_java.rl b/test/trans.d/case/clang4_java.rl new file mode 100644 index 00000000..cd5e9b93 --- /dev/null +++ b/test/trans.d/case/clang4_java.rl @@ -0,0 +1,203 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class clang4_java +{ +int pos ; +int line ; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen] = fc; + blen += 1; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {System.out.print( "ident(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + action literal {System.out.print( "literal(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + action float {System.out.print( "float(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + action integer {System.out.print( "int(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + action hex {System.out.print( "hex(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + action symbol {System.out.print( "symbol(" ); +System.out.print( line ); +System.out.print( "," ); +System.out.print( blen ); +System.out.print( "): " ); +System.out.print( new String( buffer, 0, blen ) ); +System.out.print( "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; +int cs; + +void init() +{ +pos = 0; +line = 1; + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= clang_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +}; + +static final int inplen = 2; + +public static void main (String[] args) +{ + clang4_java machine = new clang4_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/clang4_julia.rl b/test/trans.d/case/clang4_julia.rl new file mode 100644 index 00000000..86094bbb --- /dev/null +++ b/test/trans.d/case/clang4_julia.rl @@ -0,0 +1,175 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer = buffer * AbstractString(Char[fc]); +} + + # Function to clear the buffer. + action clearBuf { buffer = ""; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {print( "ident(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + action literal {print( "literal(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + action float {print( "float(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + action integer {print( "int(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + action hex {print( "hex(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + action symbol {print( "symbol(" ); +print( line ); +print( "," ); +print( length(buffer) ); +print( "): " ); +print( buffer ); +print( "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +pos = 0; +line = 0; +pos = 0; +line = 1; + + %% write init; + %% write exec; + + if ( cs >= clang_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n" ); + m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n" ); diff --git a/test/trans.d/case/clang4_ocaml.rl b/test/trans.d/case/clang4_ocaml.rl new file mode 100644 index 00000000..d9689faf --- /dev/null +++ b/test/trans.d/case/clang4_ocaml.rl @@ -0,0 +1,183 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let pos = ref 0 +let line = ref 0 + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { begin + String.set buffer blen.contents data.[p.contents]; + blen := blen.contents + 1; + end +} + + # Function to clear the buffer. + action clearBuf {begin + blen := 0; +end +} + + action incLine {line := line .contents + 1; +} + + # Functions to dump tokens as they are matched. + action ident {print_string( "ident(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + action literal {print_string( "literal(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + action float {print_string( "float(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + action integer {print_string( "int(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + action hex {print_string( "hex(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + action symbol {print_string( "symbol(" ); +print_int( line.contents ); +print_string( "," ); +print_int( blen.contents ); +print_string( "): " ); +print_string( String.sub buffer 0 blen.contents ); +print_string( "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in +pos := 0; +line := 1; + %% write init; + %% write exec; + if !cs >= clang_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n"; + exec "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n"; + () +;; + diff --git a/test/trans.d/case/clang4_ruby.rl b/test/trans.d/case/clang4_ruby.rl new file mode 100644 index 00000000..383d6d34 --- /dev/null +++ b/test/trans.d/case/clang4_ruby.rl @@ -0,0 +1,184 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer[blen] = fc; + blen += 1; +} + + # Function to clear the buffer. + action clearBuf { blen = 0; +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {print( "ident(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + action literal {print( "literal(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + action float {print( "float(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + action integer {print( "int(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + action hex {print( "hex(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + action symbol {print( "symbol(" ); +print( line ); +print( "," ); +print( blen ); +print( "): " ); +print( buffer[0..blen-1].pack( "c*" ) ); +print( "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +pos = 1 +line = 1 +pos = 0; +line = 1; + %% write init; + %% write exec; + if cs >= clang_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n", +"wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n", +] + +inplen = 2 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/clang4_rust.rl b/test/trans.d/case/clang4_rust.rl new file mode 100644 index 00000000..b77a8aec --- /dev/null +++ b/test/trans.d/case/clang4_rust.rl @@ -0,0 +1,182 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut pos : i32 = 0; +static mut line : i32 = 0; + +%%{ + machine clang; + + # Function to buffer a character. + action bufChar { buffer.push( ( fc ) as char ); +} + + # Function to clear the buffer. + action clearBuf { buffer = String::new(); +} + + action incLine {line = line + 1; +} + + # Functions to dump tokens as they are matched. + action ident {print!( "{}", "ident(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + action literal {print!( "{}", "literal(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + action float {print!( "{}", "float(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + action integer {print!( "{}", "int(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + action hex {print!( "{}", "hex(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + action symbol {print!( "{}", "symbol(" ); +print!( "{}", line ); +print!( "{}", "," ); +print!( "{}", buffer.len() ); +print!( "{}", "): " ); +print!( "{}", buffer ); +print!( "{}", "\n" ); +} + + # Alpha numberic characters or underscore. + alnumu = alnum | '_'; + + # Alpha charactres or underscore. + alphau = alpha | '_'; + + # Symbols. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving dump the symbol. + symbol = ( punct - [_'"] ) >clearBuf $bufChar %symbol; + + # Identifier. Upon entering clear the buffer. On all transitions + # buffer a character. Upon leaving, dump the identifier. + ident = (alphau . alnumu*) >clearBuf $bufChar %ident; + + # Match single characters inside literal strings. Or match + # an escape sequence. Buffers the charater matched. + sliteralChar = + ( extend - ['\\] ) @bufChar | + ( '\\' . extend @bufChar ); + dliteralChar = + ( extend - ["\\] ) @bufChar | + ( '\\' . extend @bufChar ); + + # Single quote and double quota literals. At the start clear + # the buffer. Upon leaving dump the literal. + sliteral = ('\'' @clearBuf . sliteralChar* . '\'' ) %literal; + dliteral = ('"' @clearBuf . dliteralChar* . '"' ) %literal; + literal = sliteral | dliteral; + + # Whitespace is standard ws, newlines and control codes. + whitespace = any - 33 .. 126; + + # Describe both c style comments and c++ style comments. The + # priority bump on tne terminator of the comments brings us + # out of the extend* which matches everything. + ccComment = '//' . extend* $0 . '\n' @1; + cComment = '/!' . extend* $0 . '!/' @1; + + # Match an integer. We don't bother clearing the buf or filling it. + # The float machine overlaps with int and it will do it. + integer = digit+ %integer; + + # Match a float. Upon entering the machine clear the buf, buffer + # characters on every trans and dump the float upon leaving. + float = ( digit+ . '.' . digit+ ) >clearBuf $bufChar %float; + + # Match a hex. Upon entering the hex part, clear the buf, buffer characters + # on every trans and dump the hex on leaving transitions. + hex = '0x' . xdigit+ >clearBuf $bufChar %hex; + + # Or together all the lanuage elements. + fin = ( ccComment | + cComment | + symbol | + ident | + literal | + whitespace | + integer | + float | + hex ); + + # Star the language elements. It is critical in this type of application + # that we decrease the priority of out transitions before doing so. This + # is so that when we see 'aa' we stay in the fin machine to match an ident + # of length two and not wrap around to the front to match two idents of + # length one. + clang_main = ( fin $1 %0 )*; + + # This machine matches everything, taking note of newlines. + newline = ( any | '\n' @incLine )*; + + # The final fsm is the lexer intersected with the newline machine which + # will count lines for us. Since the newline machine accepts everything, + # the strings accepted is goverened by the clang_main machine, onto which + # the newline machine overlays line counting. + main := clang_main & newline; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); +pos = 0; +line = 1; + + %% write init; + %% write exec; + + if ( cs >= clang_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "999 0xaAFF99 99.99 /!\n!/ 'lksdj' //\n\"\n\nliteral\n\n\n\"0x00aba foobardd.ddsf 0x0.9\n".to_string() ); } + unsafe { m( "wordwithnum00asdf\n000wordfollowsnum,makes new symbol\n\nfinishing early /! unfinished ...\n".to_string() ); } +} + diff --git a/test/trans.d/case/cond1.rl b/test/trans.d/case/cond1.rl new file mode 100644 index 00000000..cd96c0ec --- /dev/null +++ b/test/trans.d/case/cond1.rl @@ -0,0 +1,84 @@ +/* + * @LANG: indep + */ + +bool i; +bool j; +bool k; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one { print_str " one\n";} + action two { print_str " two\n";} + action three { print_str " three\n";} + + action seti { + if ( fc == 48 ) { + i = false; + } else { + i = true; + } + } + action setj { + if ( fc == 48 ) { + j = false; + } else { + j = true; + } + } + action setk { + if ( fc == 48 ) { + k = false; + } else { + k = true; + } + } + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + +##### INPUT ##### +"000abc\n" +"100abc\n" +"010abc\n" +"110abc\n" +"001abc\n" +"101abc\n" +"011abc\n" +"111abc\n" +##### OUTPUT ##### +FAIL + one +ACCEPT + two +ACCEPT + one + two +ACCEPT + three +ACCEPT + one + three +ACCEPT + two + three +ACCEPT + one + two + three +ACCEPT diff --git a/test/trans.d/case/cond1_asm.rl b/test/trans.d/case/cond1_asm.rl new file mode 100644 index 00000000..82904376 --- /dev/null +++ b/test/trans.d/case/cond1_asm.rl @@ -0,0 +1,319 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm i,8,8 + .text + .section .data + .comm j,8,8 + .text + .section .data + .comm k,8,8 + .text + +%%{ + machine foo; + + action c1 { + movq i (%rip), %rax + pushq %rax + movq $0, %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setne %al + movsbq %al, %rax + pushq %rax + + popq %rax +} + action c2 { + movq j (%rip), %rax + pushq %rax + movq $0, %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setne %al + movsbq %al, %rax + pushq %rax + + popq %rax +} + action c3 { + movq k (%rip), %rax + pushq %rax + movq $0, %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setne %al + movsbq %al, %rax + pushq %rax + + popq %rax +} + action one { + .section .rodata +1: + .string " one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action two { + .section .rodata +2: + .string " two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action three { + .section .rodata +3: + .string " three\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + action seti { + movsbq (%r12), %rax + pushq %rax + movq $48 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 4f + movq $0, %rax + pushq %rax + popq %rax + movq %rax, i (%rip) + jmp 5f +4: + movq $1, %rax + pushq %rax + popq %rax + movq %rax, i (%rip) +5: + +} + action setj { + movsbq (%r12), %rax + pushq %rax + movq $48 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 6f + movq $0, %rax + pushq %rax + popq %rax + movq %rax, j (%rip) + jmp 7f +6: + movq $1, %rax + pushq %rax + popq %rax + movq %rax, j (%rip) +7: + +} + action setk { + movsbq (%r12), %rax + pushq %rax + movq $48 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 8f + movq $0, %rax + pushq %rax + popq %rax + movq %rax, k (%rip) + jmp 9f +8: + movq $1, %rax + pushq %rax + popq %rax + movq %rax, k (%rip) +9: + +} + + action break { + fnbreak; + +} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq foo_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "000abc\n" +.L_inp_1: + .string "100abc\n" +.L_inp_2: + .string "010abc\n" +.L_inp_3: + .string "110abc\n" +.L_inp_4: + .string "001abc\n" +.L_inp_5: + .string "101abc\n" +.L_inp_6: + .string "011abc\n" +.L_inp_7: + .string "111abc\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + + .align 8 +inplen: + .quad 8 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/cond1_c.rl b/test/trans.d/case/cond1_c.rl new file mode 100644 index 00000000..4ec07430 --- /dev/null +++ b/test/trans.d/case/cond1_c.rl @@ -0,0 +1,121 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int i ; +int j ; +int k ; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {printf( "%s", " one\n" ); +} + action two {printf( "%s", " two\n" ); +} + action three {printf( "%s", " three\n" ); +} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +}; + +int inplen = 8; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cond1_crack.rl b/test/trans.d/case/cond1_crack.rl new file mode 100644 index 00000000..cfab3d11 --- /dev/null +++ b/test/trans.d/case/cond1_crack.rl @@ -0,0 +1,106 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int i; +int j; +int k; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {cout.format( " one\n" ); +} + action two {cout.format( " two\n" ); +} + action three {cout.format( " three\n" ); +} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "000abc\n" ); + m( "100abc\n" ); + m( "010abc\n" ); + m( "110abc\n" ); + m( "001abc\n" ); + m( "101abc\n" ); + m( "011abc\n" ); + m( "111abc\n" ); +} + +main(); diff --git a/test/trans.d/case/cond1_cs.rl b/test/trans.d/case/cond1_cs.rl new file mode 100644 index 00000000..5b1c2b42 --- /dev/null +++ b/test/trans.d/case/cond1_cs.rl @@ -0,0 +1,123 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int i; +int j; +int k; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {Console.Write( " one\n" );} + action two {Console.Write( " two\n" );} + action three {Console.Write( " three\n" );} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +}; + + +static readonly int inplen = 8; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/cond1_d.rl b/test/trans.d/case/cond1_d.rl new file mode 100644 index 00000000..113bdc36 --- /dev/null +++ b/test/trans.d/case/cond1_d.rl @@ -0,0 +1,122 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class foo +{ +int i; +int j; +int k; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {printf( "%.*s", " one\n" );} + action two {printf( "%.*s", " two\n" );} + action three {printf( "%.*s", " three\n" );} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +]; + +int inplen = 8; + +} +int main() +{ + foo m = new foo(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cond1_go.rl b/test/trans.d/case/cond1_go.rl new file mode 100644 index 00000000..20904188 --- /dev/null +++ b/test/trans.d/case/cond1_go.rl @@ -0,0 +1,103 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var i int ; +var j int ; +var k int ; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {fmt.Print( " one\n" );} + action two {fmt.Print( " two\n" );} + action three {fmt.Print( " three\n" );} + + action seti {if ( fc == 48 ) { + i = 0; + +} else { + i = 1; + +} +} + action setj {if ( fc == 48 ) { + j = 0; + +} else { + j = 1; + +} +} + action setk {if ( fc == 48 ) { + k = 0; + +} else { + k = 1; + +} +} + + action break {fnbreak; +} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= foo_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/cond1_java.rl b/test/trans.d/case/cond1_java.rl new file mode 100644 index 00000000..a49f1844 --- /dev/null +++ b/test/trans.d/case/cond1_java.rl @@ -0,0 +1,122 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class cond1_java +{ +int i ; +int j ; +int k ; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {System.out.print( " one\n" ); +} + action two {System.out.print( " two\n" ); +} + action three {System.out.print( " three\n" ); +} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +}; + +static final int inplen = 8; + +public static void main (String[] args) +{ + cond1_java machine = new cond1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/cond1_julia.rl b/test/trans.d/case/cond1_julia.rl new file mode 100644 index 00000000..ca40d50c --- /dev/null +++ b/test/trans.d/case/cond1_julia.rl @@ -0,0 +1,90 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {print( " one\n" ); +} + action two {print( " two\n" ); +} + action three {print( " three\n" ); +} + + action seti {if ( fc == 48 ) + i = 0; + +else + i = 1; + +end +} + action setj {if ( fc == 48 ) + j = 0; + +else + j = 1; + +end +} + action setk {if ( fc == 48 ) + k = 0; + +else + k = 1; + +end +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +i = 0; +j = 0; +k = 0; + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "000abc\n" ); + m( "100abc\n" ); + m( "010abc\n" ); + m( "110abc\n" ); + m( "001abc\n" ); + m( "101abc\n" ); + m( "011abc\n" ); + m( "111abc\n" ); diff --git a/test/trans.d/case/cond1_ocaml.rl b/test/trans.d/case/cond1_ocaml.rl new file mode 100644 index 00000000..4c01cd53 --- /dev/null +++ b/test/trans.d/case/cond1_ocaml.rl @@ -0,0 +1,104 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let i = ref 0 +let j = ref 0 +let k = ref 0 + +%%{ + machine foo; + + action c1 {i .contents != 0} + action c2 {j .contents != 0} + action c3 {k .contents != 0} + action one {print_string( " one\n" ); +} + action two {print_string( " two\n" ); +} + action three {print_string( " three\n" ); +} + + action seti {if fc == 48 then +begin + i := 0; + +end +else +begin + i := 1; + +end +; +} + action setj {if fc == 48 then +begin + j := 0; + +end +else +begin + j := 1; + +end +; +} + action setk {if fc == 48 then +begin + k := 0; + +end +else +begin + k := 1; + +end +; +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= foo_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "000abc\n"; + exec "100abc\n"; + exec "010abc\n"; + exec "110abc\n"; + exec "001abc\n"; + exec "101abc\n"; + exec "011abc\n"; + exec "111abc\n"; + () +;; + diff --git a/test/trans.d/case/cond1_ruby.rl b/test/trans.d/case/cond1_ruby.rl new file mode 100644 index 00000000..cfbfbcb0 --- /dev/null +++ b/test/trans.d/case/cond1_ruby.rl @@ -0,0 +1,98 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {print( " one\n" ); +} + action two {print( " two\n" ); +} + action three {print( " three\n" ); +} + + action seti {if ( fc == 48 ) + i = 0; + +else + i = 1; + +end +} + action setj {if ( fc == 48 ) + j = 0; + +else + j = 1; + +end +} + action setk {if ( fc == 48 ) + k = 0; + +else + k = 1; + +end +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +i = 1 +j = 1 +k = 1 + %% write init; + %% write exec; + if cs >= foo_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"000abc\n", +"100abc\n", +"010abc\n", +"110abc\n", +"001abc\n", +"101abc\n", +"011abc\n", +"111abc\n", +] + +inplen = 8 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/cond1_rust.rl b/test/trans.d/case/cond1_rust.rl new file mode 100644 index 00000000..829da378 --- /dev/null +++ b/test/trans.d/case/cond1_rust.rl @@ -0,0 +1,103 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut i : i8 = 0; +static mut j : i8 = 0; +static mut k : i8 = 0; + +%%{ + machine foo; + + action c1 {i != 0} + action c2 {j != 0} + action c3 {k != 0} + action one {print!( "{}", " one\n" ); +} + action two {print!( "{}", " two\n" ); +} + action three {print!( "{}", " three\n" ); +} + + action seti {if ( fc == 48 ) +{ + i = 0; + +} +else { + i = 1; + +} +} + action setj {if ( fc == 48 ) +{ + j = 0; + +} +else { + j = 1; + +} +} + action setk {if ( fc == 48 ) +{ + k = 0; + +} +else { + k = 1; + +} +} + + action break {fnbreak;} + + one = 'a' 'b' when c1 'c' @one; + two = 'a'* 'b' when c2 'c' @two; + three = 'a'+ 'b' when c3 'c' @three; + + main := + [01] @seti + [01] @setj + [01] @setk + ( one | two | three ) '\n' @break; + +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "000abc\n".to_string() ); } + unsafe { m( "100abc\n".to_string() ); } + unsafe { m( "010abc\n".to_string() ); } + unsafe { m( "110abc\n".to_string() ); } + unsafe { m( "001abc\n".to_string() ); } + unsafe { m( "101abc\n".to_string() ); } + unsafe { m( "011abc\n".to_string() ); } + unsafe { m( "111abc\n".to_string() ); } +} + diff --git a/test/trans.d/case/cond7.rl b/test/trans.d/case/cond7.rl new file mode 100644 index 00000000..2fb66b4b --- /dev/null +++ b/test/trans.d/case/cond7.rl @@ -0,0 +1,80 @@ +/* + * @LANG: indep + */ + +int i; +int c; + +%%{ + machine foo; + + action testi {i > 0} + action inc { + i = i - 1; + c = (fc); + print_str "item: "; + print_int c; + print_str "\n"; + } + + count = [0-9] @{ + i = (fc - 48); + print_str "count: "; + print_int i; + print_str "\n"; + }; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + +##### INPUT ##### +"00\n" +"019\n" +"190\n" +"1719\n" +"1040000\n" +"104000a\n" +"104000\n" +##### OUTPUT ##### +count: 0 +count: 0 +ACCEPT +count: 0 +count: 1 +item: 57 +ACCEPT +count: 1 +item: 57 +count: 0 +ACCEPT +count: 1 +item: 55 +count: 1 +item: 57 +ACCEPT +count: 1 +item: 48 +count: 4 +item: 48 +item: 48 +item: 48 +item: 48 +ACCEPT +count: 1 +item: 48 +count: 4 +item: 48 +item: 48 +item: 48 +FAIL +count: 1 +item: 48 +count: 4 +item: 48 +item: 48 +item: 48 +FAIL diff --git a/test/trans.d/case/cond7_asm.rl b/test/trans.d/case/cond7_asm.rl new file mode 100644 index 00000000..f3d4de57 --- /dev/null +++ b/test/trans.d/case/cond7_asm.rl @@ -0,0 +1,234 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm i,8,8 + .text + .section .data + .comm c,8,8 + .text + +%%{ + machine foo; + + action testi { + movq i (%rip), %rax + pushq %rax + movq $0, %rax + pushq %rax + popq %rcx + popq %rax + pushq %rax + + popq %rax +} + action inc { + movq i (%rip), %rax + pushq %rax + movq $1, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rax + movq %rax, i (%rip) + movsbq (%r12), %rax + pushq %rax + popq %rax + movq %rax, c (%rip) + .section .rodata +1: + .string "item: " + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq c(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +2: + .string "\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + count = [0-9] @{ + movsbq (%r12), %rax + pushq %rax + movq $48, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rax + movq %rax, i (%rip) + .section .rodata +3: + .string "count: " + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq i(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +4: + .string "\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq foo_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "00\n" +.L_inp_1: + .string "019\n" +.L_inp_2: + .string "190\n" +.L_inp_3: + .string "1719\n" +.L_inp_4: + .string "1040000\n" +.L_inp_5: + .string "104000a\n" +.L_inp_6: + .string "104000\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + + .align 8 +inplen: + .quad 7 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/cond7_c.rl b/test/trans.d/case/cond7_c.rl new file mode 100644 index 00000000..506b2207 --- /dev/null +++ b/test/trans.d/case/cond7_c.rl @@ -0,0 +1,87 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int i ; +int c ; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( int ) ( fc ) +; +printf( "%s", "item: " ); +printf( "%d", c ); +printf( "%s", "\n" ); +} + + count = [0-9] @{i = ( int ) ( fc - 48 ) +; +printf( "%s", "count: " ); +printf( "%d", i ); +printf( "%s", "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +}; + +int inplen = 7; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cond7_crack.rl b/test/trans.d/case/cond7_crack.rl new file mode 100644 index 00000000..e2beed73 --- /dev/null +++ b/test/trans.d/case/cond7_crack.rl @@ -0,0 +1,72 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int i; +int c; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( int ( fc ) ) +; +cout.format( "item: " ); +cout.format( c ); +cout.format( "\n" ); +} + + count = [0-9] @{i = ( int ( fc - 48 ) ) +; +cout.format( "count: " ); +cout.format( i ); +cout.format( "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "00\n" ); + m( "019\n" ); + m( "190\n" ); + m( "1719\n" ); + m( "1040000\n" ); + m( "104000a\n" ); + m( "104000\n" ); +} + +main(); diff --git a/test/trans.d/case/cond7_cs.rl b/test/trans.d/case/cond7_cs.rl new file mode 100644 index 00000000..006397fe --- /dev/null +++ b/test/trans.d/case/cond7_cs.rl @@ -0,0 +1,86 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int i; +int c; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( int ) ( fc ) +; +Console.Write( "item: " );Console.Write( c );Console.Write( "\n" );} + + count = [0-9] @{i = ( int ) ( fc - 48 ) +; +Console.Write( "count: " );Console.Write( i );Console.Write( "\n" );}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +}; + + +static readonly int inplen = 7; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/cond7_d.rl b/test/trans.d/case/cond7_d.rl new file mode 100644 index 00000000..90cc2a8c --- /dev/null +++ b/test/trans.d/case/cond7_d.rl @@ -0,0 +1,87 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class foo +{ +int i; +int c; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = cast( int ) ( fc ) +; +printf( "%.*s", "item: " );printf( "%d", c ); +printf( "%.*s", "\n" );} + + count = [0-9] @{i = cast( int ) ( fc - 48 ) +; +printf( "%.*s", "count: " );printf( "%d", i ); +printf( "%.*s", "\n" );}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +]; + +int inplen = 7; + +} +int main() +{ + foo m = new foo(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cond7_go.rl b/test/trans.d/case/cond7_go.rl new file mode 100644 index 00000000..a3e700bc --- /dev/null +++ b/test/trans.d/case/cond7_go.rl @@ -0,0 +1,71 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var i int ; +var c int ; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( int ) ( fc ) +; +fmt.Print( "item: " );fmt.Print( c );fmt.Print( "\n" );} + + count = [0-9] @{i = ( int ) ( fc - 48 ) +; +fmt.Print( "count: " );fmt.Print( i );fmt.Print( "\n" );}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= foo_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/cond7_java.rl b/test/trans.d/case/cond7_java.rl new file mode 100644 index 00000000..156a77d7 --- /dev/null +++ b/test/trans.d/case/cond7_java.rl @@ -0,0 +1,88 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class cond7_java +{ +int i ; +int c ; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( int ) ( fc ) +; +System.out.print( "item: " ); +System.out.print( c ); +System.out.print( "\n" ); +} + + count = [0-9] @{i = ( int ) ( fc - 48 ) +; +System.out.print( "count: " ); +System.out.print( i ); +System.out.print( "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= foo_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +}; + +static final int inplen = 7; + +public static void main (String[] args) +{ + cond7_java machine = new cond7_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/cond7_julia.rl b/test/trans.d/case/cond7_julia.rl new file mode 100644 index 00000000..924c3b25 --- /dev/null +++ b/test/trans.d/case/cond7_julia.rl @@ -0,0 +1,62 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = convert( Int, ( fc ) ) +; +print( "item: " ); +print( c ); +print( "\n" ); +} + + count = [0-9] @{i = convert( Int, ( fc - 48 ) ) +; +print( "count: " ); +print( i ); +print( "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +i = 0; +c = 0; + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "00\n" ); + m( "019\n" ); + m( "190\n" ); + m( "1719\n" ); + m( "1040000\n" ); + m( "104000a\n" ); + m( "104000\n" ); diff --git a/test/trans.d/case/cond7_ocaml.rl b/test/trans.d/case/cond7_ocaml.rl new file mode 100644 index 00000000..e559fdec --- /dev/null +++ b/test/trans.d/case/cond7_ocaml.rl @@ -0,0 +1,64 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let i = ref 0 +let c = ref 0 + +%%{ + machine foo; + + action testi {i .contents > 0} + action inc {i := i .contents - 1; +c := ( fc ) +; +print_string( "item: " ); +print_int( c.contents ); +print_string( "\n" ); +} + + count = [0-9] @{i := ( fc - 48 ) +; +print_string( "count: " ); +print_int( i.contents ); +print_string( "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= foo_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "00\n"; + exec "019\n"; + exec "190\n"; + exec "1719\n"; + exec "1040000\n"; + exec "104000a\n"; + exec "104000\n"; + () +;; + diff --git a/test/trans.d/case/cond7_ruby.rl b/test/trans.d/case/cond7_ruby.rl new file mode 100644 index 00000000..a2970258 --- /dev/null +++ b/test/trans.d/case/cond7_ruby.rl @@ -0,0 +1,70 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( fc ) +; +print( "item: " ); +print( c ); +print( "\n" ); +} + + count = [0-9] @{i = ( fc - 48 ) +; +print( "count: " ); +print( i ); +print( "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +i = 1 +c = 1 + %% write init; + %% write exec; + if cs >= foo_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"00\n", +"019\n", +"190\n", +"1719\n", +"1040000\n", +"104000a\n", +"104000\n", +] + +inplen = 7 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/cond7_rust.rl b/test/trans.d/case/cond7_rust.rl new file mode 100644 index 00000000..97e86165 --- /dev/null +++ b/test/trans.d/case/cond7_rust.rl @@ -0,0 +1,69 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut i : i32 = 0; +static mut c : i32 = 0; + +%%{ + machine foo; + + action testi {i > 0} + action inc {i = i - 1; +c = ( ( fc ) as i32 ) +; +print!( "{}", "item: " ); +print!( "{}", c ); +print!( "{}", "\n" ); +} + + count = [0-9] @{i = ( ( fc - 48 ) as i32 ) +; +print!( "{}", "count: " ); +print!( "{}", i ); +print!( "{}", "\n" ); +}; + + sub = + count # record the number of digits + ( digit when testi @inc )* outwhen !testi; + + main := sub sub '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= foo_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "00\n".to_string() ); } + unsafe { m( "019\n".to_string() ); } + unsafe { m( "190\n".to_string() ); } + unsafe { m( "1719\n".to_string() ); } + unsafe { m( "1040000\n".to_string() ); } + unsafe { m( "104000a\n".to_string() ); } + unsafe { m( "104000\n".to_string() ); } +} + diff --git a/test/trans.d/case/cppscan6.rl b/test/trans.d/case/cppscan6.rl new file mode 100644 index 00000000..05824150 --- /dev/null +++ b/test/trans.d/case/cppscan6.rl @@ -0,0 +1,359 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + * + * const char *data = ts; + * int len = te - ts; + * cout << "<" << tok << "> "; + * for ( int i = 0; i < len; i++ ) + * cout << data[i]; + * cout << '\n'; + */ + +ptr ts; +ptr te; +int act; +int token; + +%%{ + machine scanner; + + action comment { + token = 242; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + } + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => { + token = 193; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => { + token = 192; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{ + token = 195; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => { + token = 194; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => { + token = 218; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => { + token = 219; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => { + token = 220; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Only buffer the second item, first buffered by symbol. + '::' => { + token = 197; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '==' => { + token = 223; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '!=' => { + token = 224; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '&&' => { + token = 225; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '||' => { + token = 226; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '*=' => { + token = 227; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '/=' => { + token = 228; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '%=' => { + token = 229; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '+=' => { + token = 230; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '-=' => { + token = 231; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '&=' => { + token = 232; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '^=' => { + token = 233; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '|=' => { + token = 234; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '++' => { + token = 212; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '--' => { + token = 213; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '->' => { + token = 211; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '->*' => { + token = 214; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + '.*' => { + token = 215; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Three char compounds, first item already buffered. + '...' => { + token = 240; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Single char symbols. + ( punct - [_"'] ) => { + token = (first_token_char); + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => { + token = 241; + print_str "<"; + print_int token; + print_str "> "; + print_token; + print_str "\n"; + }; + *|; +}%% + +##### INPUT ##### +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" +"'\n'\n" +##### OUTPUT ##### +<192> "\"hi" +<241> +<242> /! +!/ +<241> + +<218> 44 +<241> +<194> .44 +<241> + +<194> 44. +<241> +<218> 44 +<241> + +<218> 44 +<241> +<46> . +<241> +<218> 44 +<241> + +<194> 44.44 +<241> + +<195> _hithere22 +ACCEPT +<193> '\'' +<192> "\n\d'\"" +<241> + +<195> hi +<241> + +<218> 99 +<241> + +<194> .99 +<241> + +<194> 99e-4 +<241> + +<214> ->* +<241> + +<226> || +<241> + +<220> 0x98 +<241> + +<218> 0 +<195> x +<241> + +<242> // + +<242> /! * !/ +ACCEPT +FAIL diff --git a/test/trans.d/case/cppscan6_asm.rl b/test/trans.d/case/cppscan6_asm.rl new file mode 100644 index 00000000..8e9a211a --- /dev/null +++ b/test/trans.d/case/cppscan6_asm.rl @@ -0,0 +1,1908 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm token,8,8 + .text + +%%{ + machine scanner; + + action comment { + movq $242, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +1: + .string "<" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +2: + .string "> " + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +3: + cmp $0, %rcx + je 4f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 3b +4: + + .section .rodata +5: + .string "\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => { + movq $193, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +6: + .string "<" + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +7: + .string "> " + .text + movq $7b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +8: + cmp $0, %rcx + je 9f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 8b +9: + + .section .rodata +10: + .string "\n" + .text + movq $10b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => { + movq $192, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +11: + .string "<" + .text + movq $11b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +12: + .string "> " + .text + movq $12b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +13: + cmp $0, %rcx + je 14f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 13b +14: + + .section .rodata +15: + .string "\n" + .text + movq $15b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{ + movq $195, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +16: + .string "<" + .text + movq $16b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +17: + .string "> " + .text + movq $17b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +18: + cmp $0, %rcx + je 19f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 18b +19: + + .section .rodata +20: + .string "\n" + .text + movq $20b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => { + movq $194, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +21: + .string "<" + .text + movq $21b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +22: + .string "> " + .text + movq $22b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +23: + cmp $0, %rcx + je 24f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 23b +24: + + .section .rodata +25: + .string "\n" + .text + movq $25b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => { + movq $218, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +26: + .string "<" + .text + movq $26b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +27: + .string "> " + .text + movq $27b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +28: + cmp $0, %rcx + je 29f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 28b +29: + + .section .rodata +30: + .string "\n" + .text + movq $30b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => { + movq $219, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +31: + .string "<" + .text + movq $31b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +32: + .string "> " + .text + movq $32b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +33: + cmp $0, %rcx + je 34f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 33b +34: + + .section .rodata +35: + .string "\n" + .text + movq $35b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => { + movq $220, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +36: + .string "<" + .text + movq $36b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +37: + .string "> " + .text + movq $37b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +38: + cmp $0, %rcx + je 39f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 38b +39: + + .section .rodata +40: + .string "\n" + .text + movq $40b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Only buffer the second item, first buffered by symbol. + '::' => { + movq $197, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +41: + .string "<" + .text + movq $41b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +42: + .string "> " + .text + movq $42b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +43: + cmp $0, %rcx + je 44f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 43b +44: + + .section .rodata +45: + .string "\n" + .text + movq $45b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '==' => { + movq $223, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +46: + .string "<" + .text + movq $46b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +47: + .string "> " + .text + movq $47b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +48: + cmp $0, %rcx + je 49f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 48b +49: + + .section .rodata +50: + .string "\n" + .text + movq $50b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '!=' => { + movq $224, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +51: + .string "<" + .text + movq $51b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +52: + .string "> " + .text + movq $52b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +53: + cmp $0, %rcx + je 54f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 53b +54: + + .section .rodata +55: + .string "\n" + .text + movq $55b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '&&' => { + movq $225, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +56: + .string "<" + .text + movq $56b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +57: + .string "> " + .text + movq $57b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +58: + cmp $0, %rcx + je 59f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 58b +59: + + .section .rodata +60: + .string "\n" + .text + movq $60b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '||' => { + movq $226, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +61: + .string "<" + .text + movq $61b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +62: + .string "> " + .text + movq $62b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +63: + cmp $0, %rcx + je 64f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 63b +64: + + .section .rodata +65: + .string "\n" + .text + movq $65b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '*=' => { + movq $227, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +66: + .string "<" + .text + movq $66b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +67: + .string "> " + .text + movq $67b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +68: + cmp $0, %rcx + je 69f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 68b +69: + + .section .rodata +70: + .string "\n" + .text + movq $70b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '/=' => { + movq $228, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +71: + .string "<" + .text + movq $71b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +72: + .string "> " + .text + movq $72b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +73: + cmp $0, %rcx + je 74f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 73b +74: + + .section .rodata +75: + .string "\n" + .text + movq $75b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '%=' => { + movq $229, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +76: + .string "<" + .text + movq $76b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +77: + .string "> " + .text + movq $77b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +78: + cmp $0, %rcx + je 79f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 78b +79: + + .section .rodata +80: + .string "\n" + .text + movq $80b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '+=' => { + movq $230, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +81: + .string "<" + .text + movq $81b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +82: + .string "> " + .text + movq $82b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +83: + cmp $0, %rcx + je 84f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 83b +84: + + .section .rodata +85: + .string "\n" + .text + movq $85b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '-=' => { + movq $231, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +86: + .string "<" + .text + movq $86b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +87: + .string "> " + .text + movq $87b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +88: + cmp $0, %rcx + je 89f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 88b +89: + + .section .rodata +90: + .string "\n" + .text + movq $90b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '&=' => { + movq $232, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +91: + .string "<" + .text + movq $91b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +92: + .string "> " + .text + movq $92b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +93: + cmp $0, %rcx + je 94f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 93b +94: + + .section .rodata +95: + .string "\n" + .text + movq $95b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '^=' => { + movq $233, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +96: + .string "<" + .text + movq $96b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +97: + .string "> " + .text + movq $97b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +98: + cmp $0, %rcx + je 99f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 98b +99: + + .section .rodata +100: + .string "\n" + .text + movq $100b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '|=' => { + movq $234, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +101: + .string "<" + .text + movq $101b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +102: + .string "> " + .text + movq $102b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +103: + cmp $0, %rcx + je 104f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 103b +104: + + .section .rodata +105: + .string "\n" + .text + movq $105b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '++' => { + movq $212, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +106: + .string "<" + .text + movq $106b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +107: + .string "> " + .text + movq $107b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +108: + cmp $0, %rcx + je 109f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 108b +109: + + .section .rodata +110: + .string "\n" + .text + movq $110b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '--' => { + movq $213, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +111: + .string "<" + .text + movq $111b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +112: + .string "> " + .text + movq $112b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +113: + cmp $0, %rcx + je 114f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 113b +114: + + .section .rodata +115: + .string "\n" + .text + movq $115b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '->' => { + movq $211, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +116: + .string "<" + .text + movq $116b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +117: + .string "> " + .text + movq $117b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +118: + cmp $0, %rcx + je 119f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 118b +119: + + .section .rodata +120: + .string "\n" + .text + movq $120b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '->*' => { + movq $214, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +121: + .string "<" + .text + movq $121b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +122: + .string "> " + .text + movq $122b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +123: + cmp $0, %rcx + je 124f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 123b +124: + + .section .rodata +125: + .string "\n" + .text + movq $125b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '.*' => { + movq $215, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +126: + .string "<" + .text + movq $126b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +127: + .string "> " + .text + movq $127b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +128: + cmp $0, %rcx + je 129f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 128b +129: + + .section .rodata +130: + .string "\n" + .text + movq $130b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Three char compounds, first item already buffered. + '...' => { + movq $240, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +131: + .string "<" + .text + movq $131b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +132: + .string "> " + .text + movq $132b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +133: + cmp $0, %rcx + je 134f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 133b +134: + + .section .rodata +135: + .string "\n" + .text + movq $135b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Single char symbols. + ( punct - [_"'] ) => { + movq -16(%rbp), %rax + movsbq (%rax), %rcx + pushq %rcx + popq %rax + movq %rax, token (%rip) + .section .rodata +136: + .string "<" + .text + movq $136b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +137: + .string "> " + .text + movq $137b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +138: + cmp $0, %rcx + je 139f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 138b +139: + + .section .rodata +140: + .string "\n" + .text + movq $140b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => { + movq $241, %rax + pushq %rax + popq %rax + movq %rax, token (%rip) + .section .rodata +141: + .string "<" + .text + movq $141b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq token(%rip), %rax + pushq %rax + movq $.L_fmt_int, %rdi + popq %rsi + movq $0, %rax + call printf + .section .rodata +142: + .string "> " + .text + movq $142b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -16(%rbp), %rax # ts + movq -24(%rbp), %rcx # te + subq %rax, %rcx # length +143: + cmp $0, %rcx + je 144f + movsbl (%rax), %edi + push %rax + push %rcx + call putchar + pop %rcx + pop %rax + addq $1, %rax + subq $1, %rcx + jmp 143b +144: + + .section .rodata +145: + .string "\n" + .text + movq $145b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq scanner_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" +.L_inp_1: + .string "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" +.L_inp_2: + .string "'\n'\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + + .align 8 +inplen: + .quad 3 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/cppscan6_c.rl b/test/trans.d/case/cppscan6_c.rl new file mode 100644 index 00000000..bc774d92 --- /dev/null +++ b/test/trans.d/case/cppscan6_c.rl @@ -0,0 +1,278 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char * ts ; +char * te ; +int act ; +int token ; + +%%{ + machine scanner; + + action comment {token = 242; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '==' => {token = 223; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '!=' => {token = 224; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '&&' => {token = 225; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '||' => {token = 226; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '*=' => {token = 227; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '/=' => {token = 228; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '%=' => {token = 229; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '+=' => {token = 230; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '-=' => {token = 231; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '&=' => {token = 232; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '^=' => {token = 233; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '|=' => {token = 234; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '++' => {token = 212; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '--' => {token = 213; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '->' => {token = 211; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '->*' => {token = 214; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + '.*' => {token = 215; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( int ) ( ts[0] ) +; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +printf( "%s", "<" ); +printf( "%d", token ); +printf( "%s", "> " ); +fwrite ( ts , 1 , te - ts , stdout );printf( "%s", "\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +}; + +int inplen = 3; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cppscan6_crack.rl b/test/trans.d/case/cppscan6_crack.rl new file mode 100644 index 00000000..5cf24759 --- /dev/null +++ b/test/trans.d/case/cppscan6_crack.rl @@ -0,0 +1,323 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int + ts; +int + te; +int act; +int token; + +%%{ + machine scanner; + + action comment {token = 242; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '==' => {token = 223; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '!=' => {token = 224; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '&&' => {token = 225; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '||' => {token = 226; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '*=' => {token = 227; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '/=' => {token = 228; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '%=' => {token = 229; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '+=' => {token = 230; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '-=' => {token = 231; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '&=' => {token = 232; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '^=' => {token = 233; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '|=' => {token = 234; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '++' => {token = 212; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '--' => {token = 213; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '->' => {token = 211; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '->*' => {token = 214; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + '.*' => {token = 215; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( int ( data[ts] ) ) +; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +cout.format( "<" ); +cout.format( token ); +cout.format( "> " ); +int len = uintz(te) - uintz(ts); +cout.write( Buffer(data + uintz(ts), len) ); +cout.format( "\n" ); +}; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" ); + m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" ); + m( "'\n'\n" ); +} + +main(); diff --git a/test/trans.d/case/cppscan6_cs.rl b/test/trans.d/case/cppscan6_cs.rl new file mode 100644 index 00000000..11116bba --- /dev/null +++ b/test/trans.d/case/cppscan6_cs.rl @@ -0,0 +1,195 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int ts; +int te; +int act; +int token; + +%%{ + machine scanner; + + action comment {token = 242; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '==' => {token = 223; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '!=' => {token = 224; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '&&' => {token = 225; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '||' => {token = 226; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '*=' => {token = 227; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '/=' => {token = 228; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '%=' => {token = 229; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '+=' => {token = 230; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '-=' => {token = 231; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '&=' => {token = 232; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '^=' => {token = 233; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '|=' => {token = 234; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '++' => {token = 212; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '--' => {token = 213; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '->' => {token = 211; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '->*' => {token = 214; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + '.*' => {token = 215; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( int ) ( data[ts] ) +; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +Console.Write( "<" );Console.Write( token );Console.Write( "> " );Console.Write( new String( data , ts , te - ts ) ); +Console.Write( "\n" );}; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +}; + + +static readonly int inplen = 3; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/cppscan6_d.rl b/test/trans.d/case/cppscan6_d.rl new file mode 100644 index 00000000..f0deb0d7 --- /dev/null +++ b/test/trans.d/case/cppscan6_d.rl @@ -0,0 +1,195 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class scanner +{ +const(char) * ts; +const(char) * te; +int act; +int token; + +%%{ + machine scanner; + + action comment {token = 242; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '==' => {token = 223; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '!=' => {token = 224; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '&&' => {token = 225; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '||' => {token = 226; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '*=' => {token = 227; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '/=' => {token = 228; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '%=' => {token = 229; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '+=' => {token = 230; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '-=' => {token = 231; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '&=' => {token = 232; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '^=' => {token = 233; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '|=' => {token = 234; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '++' => {token = 212; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '--' => {token = 213; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '->' => {token = 211; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '->*' => {token = 214; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + '.*' => {token = 215; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Single char symbols. + ( punct - [_"'] ) => {token = cast( int ) ( ts[0] ) +; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +printf( "%.*s", "<" );printf( "%d", token ); +printf( "%.*s", "> " );printf( "%.*s", ts[0..(te - ts)] );printf( "%.*s", "\n" );}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +]; + +int inplen = 3; + +} +int main() +{ + scanner m = new scanner(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/cppscan6_go.rl b/test/trans.d/case/cppscan6_go.rl new file mode 100644 index 00000000..1616a67f --- /dev/null +++ b/test/trans.d/case/cppscan6_go.rl @@ -0,0 +1,152 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var ts int ; +var te int ; +var act int ; +var token int ; + +%%{ + machine scanner; + + action comment {token = 242; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '==' => {token = 223; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '!=' => {token = 224; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '&&' => {token = 225; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '||' => {token = 226; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '*=' => {token = 227; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '/=' => {token = 228; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '%=' => {token = 229; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '+=' => {token = 230; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '-=' => {token = 231; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '&=' => {token = 232; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '^=' => {token = 233; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '|=' => {token = 234; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '++' => {token = 212; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '--' => {token = 213; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '->' => {token = 211; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '->*' => {token = 214; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + '.*' => {token = 215; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( int ) ( data[ts] ) +; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +fmt.Print( "<" );fmt.Print( token );fmt.Print( "> " );fmt.Print( data[ts:te] );fmt.Print( "\n" );}; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= scanner_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/cppscan6_java.rl b/test/trans.d/case/cppscan6_java.rl new file mode 100644 index 00000000..fbad9117 --- /dev/null +++ b/test/trans.d/case/cppscan6_java.rl @@ -0,0 +1,339 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class cppscan6_java +{ +int + ts ; +int + te ; +int act ; +int token ; + +%%{ + machine scanner; + + action comment {token = 242; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '==' => {token = 223; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '!=' => {token = 224; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '&&' => {token = 225; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '||' => {token = 226; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '*=' => {token = 227; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '/=' => {token = 228; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '%=' => {token = 229; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '+=' => {token = 230; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '-=' => {token = 231; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '&=' => {token = 232; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '^=' => {token = 233; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '|=' => {token = 234; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '++' => {token = 212; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '--' => {token = 213; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '->' => {token = 211; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '->*' => {token = 214; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + '.*' => {token = 215; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( int ) ( data[ts] ) +; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +System.out.print( "<" ); +System.out.print( token ); +System.out.print( "> " ); +_s = new String( data, ts, te - ts ); +System.out.print( _s ); +System.out.print( "\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +}; + +static final int inplen = 3; + +public static void main (String[] args) +{ + cppscan6_java machine = new cppscan6_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/cppscan6_julia.rl b/test/trans.d/case/cppscan6_julia.rl new file mode 100644 index 00000000..ff1dcac4 --- /dev/null +++ b/test/trans.d/case/cppscan6_julia.rl @@ -0,0 +1,281 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine scanner; + + action comment {token = 242; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '==' => {token = 223; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '!=' => {token = 224; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '&&' => {token = 225; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '||' => {token = 226; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '*=' => {token = 227; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '/=' => {token = 228; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '%=' => {token = 229; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '+=' => {token = 230; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '-=' => {token = 231; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '&=' => {token = 232; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '^=' => {token = 233; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '|=' => {token = 234; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '++' => {token = 212; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '--' => {token = 213; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '->' => {token = 211; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '->*' => {token = 214; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + '.*' => {token = 215; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = convert( Int, ( data[ts+1] ) ) +; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +print( "<" ); +print( token ); +print( "> " ); +print( data[(ts+1) : (te)] ) +print( "\n" ); +}; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +ts = 0; +te = 0; +act = 0; +token = 0; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22" ); + m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/" ); + m( "'\n'\n" ); diff --git a/test/trans.d/case/cppscan6_ocaml.rl b/test/trans.d/case/cppscan6_ocaml.rl new file mode 100644 index 00000000..c6af74dc --- /dev/null +++ b/test/trans.d/case/cppscan6_ocaml.rl @@ -0,0 +1,255 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let token = ref 0 + +%%{ + machine scanner; + + action comment {token := 242; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token := 193; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token := 192; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token := 195; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token := 194; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token := 218; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token := 219; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token := 220; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token := 197; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '==' => {token := 223; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '!=' => {token := 224; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '&&' => {token := 225; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '||' => {token := 226; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '*=' => {token := 227; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '/=' => {token := 228; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '%=' => {token := 229; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '+=' => {token := 230; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '-=' => {token := 231; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '&=' => {token := 232; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '^=' => {token := 233; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '|=' => {token := 234; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '++' => {token := 212; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '--' => {token := 213; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '->' => {token := 211; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '->*' => {token := 214; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + '.*' => {token := 215; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token := 240; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token := ( ( Char.code data.[ts.contents] ) ) +; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token := 241; +print_string( "<" ); +print_int( token.contents ); +print_string( "> " ); +for i = ts.contents to te.contents - 1 do print_char data.[i] done; print_string( "\n" ); +}; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= scanner_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22"; + exec "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/"; + exec "'\n'\n"; + () +;; + diff --git a/test/trans.d/case/cppscan6_ruby.rl b/test/trans.d/case/cppscan6_ruby.rl new file mode 100644 index 00000000..58079620 --- /dev/null +++ b/test/trans.d/case/cppscan6_ruby.rl @@ -0,0 +1,318 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine scanner; + + action comment {token = 242; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '==' => {token = 223; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '!=' => {token = 224; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '&&' => {token = 225; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '||' => {token = 226; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '*=' => {token = 227; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '/=' => {token = 228; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '%=' => {token = 229; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '+=' => {token = 230; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '-=' => {token = 231; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '&=' => {token = 232; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '^=' => {token = 233; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '|=' => {token = 234; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '++' => {token = 212; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '--' => {token = 213; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '->' => {token = 211; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '->*' => {token = 214; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + '.*' => {token = 215; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( data[ts].ord ) +; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +print( "<" ); +print( token ); +print( "> " ); +_m = data[ts..te-1]; +print( _m ); +print( "\n" ); +}; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +ts = 1 +te = 1 +act = 1 +token = 1 + %% write init; + %% write exec; + if cs >= scanner_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22", +"'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/", +"'\n'\n", +] + +inplen = 3 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/cppscan6_rust.rl b/test/trans.d/case/cppscan6_rust.rl new file mode 100644 index 00000000..edd821c6 --- /dev/null +++ b/test/trans.d/case/cppscan6_rust.rl @@ -0,0 +1,406 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut token : i32 = 0; + +%%{ + machine scanner; + + action comment {token = 242; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +} + + + main := |* + + # Single and double literals. + ( 'L'? "'" ( [^'\\\n] | '\\' any )* "'" ) + => {token = 193; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + ( 'L'? '"' ( [^"\\\n] | '\\' any )* '"' ) + => {token = 192; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Identifiers + ( [a-zA-Z_] [a-zA-Z0-9_]* ) + =>{token = 195; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Floating literals. + fract_const = digit* '.' digit+ | digit+ '.'; + exponent = [eE] [+\-]? digit+; + float_suffix = [flFL]; + + ( fract_const exponent? float_suffix? | + digit+ exponent float_suffix? ) + => {token = 194; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Integer decimal. Leading part buffered by float. + ( ( '0' | [1-9] [0-9]* ) [ulUL]? ) + => {token = 218; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Integer octal. Leading part buffered by float. + ( '0' [0-9]+ [ulUL]? ) + => {token = 219; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Integer hex. Leading 0 buffered by float. + ( '0' ( 'x' [0-9a-fA-F]+ [ulUL]? ) ) + => {token = 220; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Only buffer the second item, first buffered by symbol. + '::' => {token = 197; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '==' => {token = 223; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '!=' => {token = 224; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '&&' => {token = 225; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '||' => {token = 226; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '*=' => {token = 227; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '/=' => {token = 228; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '%=' => {token = 229; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '+=' => {token = 230; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '-=' => {token = 231; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '&=' => {token = 232; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '^=' => {token = 233; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '|=' => {token = 234; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '++' => {token = 212; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '--' => {token = 213; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '->' => {token = 211; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '->*' => {token = 214; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + '.*' => {token = 215; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Three char compounds, first item already buffered. + '...' => {token = 240; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Single char symbols. + ( punct - [_"'] ) => {token = ( ( data[ts as usize] ) as i32 ) +; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + + # Comments and whitespace. + '/!' ( any* $0 '!/' @1 ) => comment; + '//' ( any* $0 '\n' @1 ) => comment; + ( any - 33..126 )+ => {token = 241; +print!( "{}", "<" ); +print!( "{}", token ); +print!( "{}", "> " ); +let s = match std::str::from_utf8(&data[ts as usize .. te as usize]) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence: {}", e), + }; +print!( "{}", s ); +print!( "{}", "\n" ); +}; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "\"\\\"hi\" /!\n!/\n44 .44\n44. 44\n44 . 44\n44.44\n_hithere22".to_string() ); } + unsafe { m( "'\\''\"\\n\\d'\\\"\"\nhi\n99\n.99\n99e-4\n->*\n||\n0x98\n0x\n//\n/! * !/".to_string() ); } + unsafe { m( "'\n'\n".to_string() ); } +} + diff --git a/test/trans.d/case/curs1.rl b/test/trans.d/case/curs1.rl new file mode 100644 index 00000000..71c5c43c --- /dev/null +++ b/test/trans.d/case/curs1.rl @@ -0,0 +1,34 @@ +/* + * @LANG: indep + */ + +int return_to; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + fnext *return_to; + }; + + two := 'two' @{ + print_str "two\n"; + fnext *return_to; + }; + + main := + '1' @{ return_to = fcurs; fnext one; } + | '2' @{ return_to = fcurs; fnext two; } + | '\n'; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/curs1_asm.rl b/test/trans.d/case/curs1_asm.rl new file mode 100644 index 00000000..8b71c052 --- /dev/null +++ b/test/trans.d/case/curs1_asm.rl @@ -0,0 +1,171 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm return_to,8,8 + .text + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq return_to(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq return_to(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + main := + '1' @{ + fcurs; + pushq %rax + popq %rax + movq %rax, return_to (%rip) +fnext one; + +} + | '2' @{ + fcurs; + pushq %rax + popq %rax + movq %rax, return_to (%rip) +fnext two; + +} + | '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq curs1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/curs1_c.rl b/test/trans.d/case/curs1_c.rl new file mode 100644 index 00000000..781aa33e --- /dev/null +++ b/test/trans.d/case/curs1_c.rl @@ -0,0 +1,73 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int return_to ; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +fnext *return_to;}; + + two := 'two' @{printf( "%s", "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= curs1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/curs1_crack.rl b/test/trans.d/case/curs1_crack.rl new file mode 100644 index 00000000..f1b1126d --- /dev/null +++ b/test/trans.d/case/curs1_crack.rl @@ -0,0 +1,58 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int return_to; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +fnext *return_to;}; + + two := 'two' @{cout.format( "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= curs1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/curs1_cs.rl b/test/trans.d/case/curs1_cs.rl new file mode 100644 index 00000000..fe525f85 --- /dev/null +++ b/test/trans.d/case/curs1_cs.rl @@ -0,0 +1,76 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int return_to; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );fnext *return_to;}; + + two := 'two' @{Console.Write( "two\n" );fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= curs1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/curs1_d.rl b/test/trans.d/case/curs1_d.rl new file mode 100644 index 00000000..3bce97a4 --- /dev/null +++ b/test/trans.d/case/curs1_d.rl @@ -0,0 +1,75 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class curs1 +{ +int return_to; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );fnext *return_to;}; + + two := 'two' @{printf( "%.*s", "two\n" );fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= curs1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + curs1 m = new curs1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/curs1_go.rl b/test/trans.d/case/curs1_go.rl new file mode 100644 index 00000000..1c9058a2 --- /dev/null +++ b/test/trans.d/case/curs1_go.rl @@ -0,0 +1,67 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var return_to int ; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );fnext *return_to; + +}; + + two := 'two' @{fmt.Print( "two\n" );fnext *return_to; + +}; + + main := + '1' @{return_to = fcurs; +fnext one; +} + | '2' @{return_to = fcurs; +fnext two; +} + | '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= curs1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/curs1_java.rl b/test/trans.d/case/curs1_java.rl new file mode 100644 index 00000000..c44dd6c1 --- /dev/null +++ b/test/trans.d/case/curs1_java.rl @@ -0,0 +1,74 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class curs1_java +{ +int return_to ; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{System.out.print( "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= curs1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + curs1_java machine = new curs1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/curs1_julia.rl b/test/trans.d/case/curs1_julia.rl new file mode 100644 index 00000000..10972c82 --- /dev/null +++ b/test/trans.d/case/curs1_julia.rl @@ -0,0 +1,48 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{print( "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +return_to = 0; + + %% write init; + %% write exec; + + if ( cs >= curs1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/curs1_ocaml.rl b/test/trans.d/case/curs1_ocaml.rl new file mode 100644 index 00000000..b79dc73e --- /dev/null +++ b/test/trans.d/case/curs1_ocaml.rl @@ -0,0 +1,52 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let return_to = ref 0 + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{print_string( "one\n" ); +fnext *return_to.contents; +}; + + two := 'two' @{print_string( "two\n" ); +fnext *return_to.contents; +}; + + main := + '1' @{return_to := fcurs; +fnext one; } + | '2' @{return_to := fcurs; +fnext two; } + | '\n'; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= curs1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1one2two1one\n"; + () +;; + diff --git a/test/trans.d/case/curs1_ruby.rl b/test/trans.d/case/curs1_ruby.rl new file mode 100644 index 00000000..dfa48b2f --- /dev/null +++ b/test/trans.d/case/curs1_ruby.rl @@ -0,0 +1,56 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{print( "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +return_to = 1 + %% write init; + %% write exec; + if cs >= curs1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1one2two1one\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/curs1_rust.rl b/test/trans.d/case/curs1_rust.rl new file mode 100644 index 00000000..3c666c45 --- /dev/null +++ b/test/trans.d/case/curs1_rust.rl @@ -0,0 +1,55 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut return_to : i32 = 0; + +%%{ + machine curs1; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +fnext *return_to;}; + + two := 'two' @{print!( "{}", "two\n" ); +fnext *return_to;}; + + main := + '1' @{return_to = fcurs; +fnext one;} + | '2' @{return_to = fcurs; +fnext two;} + | '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= curs1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/empty1.rl b/test/trans.d/case/empty1.rl new file mode 100644 index 00000000..39078902 --- /dev/null +++ b/test/trans.d/case/empty1.rl @@ -0,0 +1,15 @@ +/* + * @LANG: indep + */ + +%%{ + machine empty1; + main := empty; +}%% + +##### INPUT ##### +"" +"x" +##### OUTPUT ##### +FAIL +FAIL diff --git a/test/trans.d/case/empty1_asm.rl b/test/trans.d/case/empty1_asm.rl new file mode 100644 index 00000000..5f283c9c --- /dev/null +++ b/test/trans.d/case/empty1_asm.rl @@ -0,0 +1,115 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine empty1; + main := empty; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq empty1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "" +.L_inp_1: + .string "x" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + + .align 8 +inplen: + .quad 2 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/empty1_c.rl b/test/trans.d/case/empty1_c.rl new file mode 100644 index 00000000..be0b4917 --- /dev/null +++ b/test/trans.d/case/empty1_c.rl @@ -0,0 +1,61 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= empty1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"", +"x", +}; + +int inplen = 2; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/empty1_crack.rl b/test/trans.d/case/empty1_crack.rl new file mode 100644 index 00000000..f9ef6600 --- /dev/null +++ b/test/trans.d/case/empty1_crack.rl @@ -0,0 +1,46 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= empty1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "" ); + m( "x" ); +} + +main(); diff --git a/test/trans.d/case/empty1_cs.rl b/test/trans.d/case/empty1_cs.rl new file mode 100644 index 00000000..b1c493aa --- /dev/null +++ b/test/trans.d/case/empty1_cs.rl @@ -0,0 +1,66 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine empty1; + main := empty; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= empty1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"", +"x", +}; + + +static readonly int inplen = 2; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/empty1_d.rl b/test/trans.d/case/empty1_d.rl new file mode 100644 index 00000000..3593f520 --- /dev/null +++ b/test/trans.d/case/empty1_d.rl @@ -0,0 +1,65 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class empty1 +{ + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= empty1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"", +"x", +]; + +int inplen = 2; + +} +int main() +{ + empty1 m = new empty1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/empty1_go.rl b/test/trans.d/case/empty1_go.rl new file mode 100644 index 00000000..b3d535c1 --- /dev/null +++ b/test/trans.d/case/empty1_go.rl @@ -0,0 +1,51 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine empty1; + main := empty; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= empty1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"", +"x", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/empty1_java.rl b/test/trans.d/case/empty1_java.rl new file mode 100644 index 00000000..54f354c3 --- /dev/null +++ b/test/trans.d/case/empty1_java.rl @@ -0,0 +1,62 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class empty1_java +{ + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= empty1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"", +"x", +}; + +static final int inplen = 2; + +public static void main (String[] args) +{ + empty1_java machine = new empty1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/empty1_julia.rl b/test/trans.d/case/empty1_julia.rl new file mode 100644 index 00000000..7935b34d --- /dev/null +++ b/test/trans.d/case/empty1_julia.rl @@ -0,0 +1,36 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= empty1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "" ); + m( "x" ); diff --git a/test/trans.d/case/empty1_ocaml.rl b/test/trans.d/case/empty1_ocaml.rl new file mode 100644 index 00000000..f9e0249d --- /dev/null +++ b/test/trans.d/case/empty1_ocaml.rl @@ -0,0 +1,38 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine empty1; + main := empty; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= empty1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec ""; + exec "x"; + () +;; + diff --git a/test/trans.d/case/empty1_ruby.rl b/test/trans.d/case/empty1_ruby.rl new file mode 100644 index 00000000..340af2bc --- /dev/null +++ b/test/trans.d/case/empty1_ruby.rl @@ -0,0 +1,44 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= empty1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"", +"x", +] + +inplen = 2 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/empty1_rust.rl b/test/trans.d/case/empty1_rust.rl new file mode 100644 index 00000000..af89c9a7 --- /dev/null +++ b/test/trans.d/case/empty1_rust.rl @@ -0,0 +1,43 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine empty1; + main := empty; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= empty1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "".to_string() ); } + unsafe { m( "x".to_string() ); } +} + diff --git a/test/trans.d/case/eofact.rl b/test/trans.d/case/eofact.rl new file mode 100644 index 00000000..83ad2a7e --- /dev/null +++ b/test/trans.d/case/eofact.rl @@ -0,0 +1,51 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + * + * Test works with split code gen. + */ + +%%{ + machine eofact; + + action a1 { print_str "a1\n"; } + action a2 { print_str "a2\n"; } + action a3 { print_str "a3\n"; } + action a4 { print_str "a4\n"; } + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + +##### INPUT ##### +"" +"h" +"hell" +"hello" +"hello\n" +"t" +"ther" +"there" +"friend" +##### OUTPUT ##### +a1 +a3 +FAIL +a1 +FAIL +a1 +FAIL +a2 +ACCEPT +ACCEPT +a3 +FAIL +a3 +FAIL +a4 +ACCEPT +FAIL diff --git a/test/trans.d/case/eofact_asm.rl b/test/trans.d/case/eofact_asm.rl new file mode 100644 index 00000000..22937aed --- /dev/null +++ b/test/trans.d/case/eofact_asm.rl @@ -0,0 +1,196 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine eofact; + + action a1 { + .section .rodata +1: + .string "a1\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action a2 { + .section .rodata +2: + .string "a2\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action a3 { + .section .rodata +3: + .string "a3\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action a4 { + .section .rodata +4: + .string "a4\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq eofact_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "" +.L_inp_1: + .string "h" +.L_inp_2: + .string "hell" +.L_inp_3: + .string "hello" +.L_inp_4: + .string "hello\n" +.L_inp_5: + .string "t" +.L_inp_6: + .string "ther" +.L_inp_7: + .string "there" +.L_inp_8: + .string "friend" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + + .align 8 +inplen: + .quad 9 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/eofact_c.rl b/test/trans.d/case/eofact_c.rl new file mode 100644 index 00000000..65bd9b9d --- /dev/null +++ b/test/trans.d/case/eofact_c.rl @@ -0,0 +1,84 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine eofact; + + action a1 {printf( "%s", "a1\n" ); +} + action a2 {printf( "%s", "a2\n" ); +} + action a3 {printf( "%s", "a3\n" ); +} + action a4 {printf( "%s", "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= eofact_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +}; + +int inplen = 9; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/eofact_crack.rl b/test/trans.d/case/eofact_crack.rl new file mode 100644 index 00000000..eb2e924a --- /dev/null +++ b/test/trans.d/case/eofact_crack.rl @@ -0,0 +1,69 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine eofact; + + action a1 {cout.format( "a1\n" ); +} + action a2 {cout.format( "a2\n" ); +} + action a3 {cout.format( "a3\n" ); +} + action a4 {cout.format( "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= eofact_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "" ); + m( "h" ); + m( "hell" ); + m( "hello" ); + m( "hello\n" ); + m( "t" ); + m( "ther" ); + m( "there" ); + m( "friend" ); +} + +main(); diff --git a/test/trans.d/case/eofact_cs.rl b/test/trans.d/case/eofact_cs.rl new file mode 100644 index 00000000..a1918623 --- /dev/null +++ b/test/trans.d/case/eofact_cs.rl @@ -0,0 +1,84 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine eofact; + + action a1 {Console.Write( "a1\n" );} + action a2 {Console.Write( "a2\n" );} + action a3 {Console.Write( "a3\n" );} + action a4 {Console.Write( "a4\n" );} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= eofact_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +}; + + +static readonly int inplen = 9; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/eofact_d.rl b/test/trans.d/case/eofact_d.rl new file mode 100644 index 00000000..5c975f0f --- /dev/null +++ b/test/trans.d/case/eofact_d.rl @@ -0,0 +1,84 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class eofact +{ + + + +%%{ + machine eofact; + + action a1 {printf( "%.*s", "a1\n" );} + action a2 {printf( "%.*s", "a2\n" );} + action a3 {printf( "%.*s", "a3\n" );} + action a4 {printf( "%.*s", "a4\n" );} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= eofact_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +]; + +int inplen = 9; + +} +int main() +{ + eofact m = new eofact(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/eofact_go.rl b/test/trans.d/case/eofact_go.rl new file mode 100644 index 00000000..caa7d707 --- /dev/null +++ b/test/trans.d/case/eofact_go.rl @@ -0,0 +1,70 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine eofact; + + action a1 {fmt.Print( "a1\n" );} + action a2 {fmt.Print( "a2\n" );} + action a3 {fmt.Print( "a3\n" );} + action a4 {fmt.Print( "a4\n" );} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= eofact_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/eofact_java.rl b/test/trans.d/case/eofact_java.rl new file mode 100644 index 00000000..9496714c --- /dev/null +++ b/test/trans.d/case/eofact_java.rl @@ -0,0 +1,85 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class eofact_java +{ + + + +%%{ + machine eofact; + + action a1 {System.out.print( "a1\n" ); +} + action a2 {System.out.print( "a2\n" ); +} + action a3 {System.out.print( "a3\n" ); +} + action a4 {System.out.print( "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= eofact_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +}; + +static final int inplen = 9; + +public static void main (String[] args) +{ + eofact_java machine = new eofact_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/eofact_julia.rl b/test/trans.d/case/eofact_julia.rl new file mode 100644 index 00000000..4b3eecd7 --- /dev/null +++ b/test/trans.d/case/eofact_julia.rl @@ -0,0 +1,58 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine eofact; + + action a1 {print( "a1\n" ); +} + action a2 {print( "a2\n" ); +} + action a3 {print( "a3\n" ); +} + action a4 {print( "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= eofact_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "" ); + m( "h" ); + m( "hell" ); + m( "hello" ); + m( "hello\n" ); + m( "t" ); + m( "ther" ); + m( "there" ); + m( "friend" ); diff --git a/test/trans.d/case/eofact_ocaml.rl b/test/trans.d/case/eofact_ocaml.rl new file mode 100644 index 00000000..e8579c32 --- /dev/null +++ b/test/trans.d/case/eofact_ocaml.rl @@ -0,0 +1,61 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine eofact; + + action a1 {print_string( "a1\n" ); +} + action a2 {print_string( "a2\n" ); +} + action a3 {print_string( "a3\n" ); +} + action a4 {print_string( "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= eofact_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec ""; + exec "h"; + exec "hell"; + exec "hello"; + exec "hello\n"; + exec "t"; + exec "ther"; + exec "there"; + exec "friend"; + () +;; + diff --git a/test/trans.d/case/eofact_ruby.rl b/test/trans.d/case/eofact_ruby.rl new file mode 100644 index 00000000..6cd5f4e5 --- /dev/null +++ b/test/trans.d/case/eofact_ruby.rl @@ -0,0 +1,66 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine eofact; + + action a1 {print( "a1\n" ); +} + action a2 {print( "a2\n" ); +} + action a3 {print( "a3\n" ); +} + action a4 {print( "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= eofact_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"", +"h", +"hell", +"hello", +"hello\n", +"t", +"ther", +"there", +"friend", +] + +inplen = 9 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/eofact_rust.rl b/test/trans.d/case/eofact_rust.rl new file mode 100644 index 00000000..5c8492dd --- /dev/null +++ b/test/trans.d/case/eofact_rust.rl @@ -0,0 +1,65 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine eofact; + + action a1 {print!( "{}", "a1\n" ); +} + action a2 {print!( "{}", "a2\n" ); +} + action a3 {print!( "{}", "a3\n" ); +} + action a4 {print!( "{}", "a4\n" ); +} + + + main := ( + 'hello' @eof a1 %eof a2 '\n'? | + 'there' @eof a3 %eof a4 + ); + +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= eofact_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "".to_string() ); } + unsafe { m( "h".to_string() ); } + unsafe { m( "hell".to_string() ); } + unsafe { m( "hello".to_string() ); } + unsafe { m( "hello\n".to_string() ); } + unsafe { m( "t".to_string() ); } + unsafe { m( "ther".to_string() ); } + unsafe { m( "there".to_string() ); } + unsafe { m( "friend".to_string() ); } +} + diff --git a/test/trans.d/case/erract2.rl b/test/trans.d/case/erract2.rl new file mode 100644 index 00000000..f6007151 --- /dev/null +++ b/test/trans.d/case/erract2.rl @@ -0,0 +1,90 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + * + * Test error actions. + */ + +%%{ + machine erract; + + action err_start { print_str "err_start\n"; } + action err_all { print_str "err_all\n"; } + action err_middle { print_str "err_middle\n"; } + action err_out { print_str "err_out\n"; } + + action eof_start { print_str "eof_start\n"; } + action eof_all { print_str "eof_all\n"; } + action eof_middle { print_str "eof_middle\n"; } + action eof_out { print_str "eof_out\n"; } + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + +##### INPUT ##### +"" +"h" +"x" +"he" +"hx" +"hel" +"hex" +"hell" +"helx" +"hello" +"hellx" +"hello\n" +"hellox" +##### OUTPUT ##### +err_start +eof_start +err_all +eof_all +FAIL +err_all +err_middle +eof_all +eof_middle +FAIL +err_start +err_all +FAIL +err_all +err_middle +eof_all +eof_middle +FAIL +err_all +err_middle +FAIL +err_all +err_middle +eof_all +eof_middle +FAIL +err_all +err_middle +FAIL +err_all +err_middle +eof_all +eof_middle +FAIL +err_all +err_middle +FAIL +err_all +err_out +eof_all +eof_out +FAIL +err_all +err_middle +FAIL +ACCEPT +err_all +err_out +FAIL diff --git a/test/trans.d/case/erract2_asm.rl b/test/trans.d/case/erract2_asm.rl new file mode 100644 index 00000000..11e74664 --- /dev/null +++ b/test/trans.d/case/erract2_asm.rl @@ -0,0 +1,259 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine erract; + + action err_start { + .section .rodata +1: + .string "err_start\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action err_all { + .section .rodata +2: + .string "err_all\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action err_middle { + .section .rodata +3: + .string "err_middle\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action err_out { + .section .rodata +4: + .string "err_out\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + action eof_start { + .section .rodata +5: + .string "eof_start\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action eof_all { + .section .rodata +6: + .string "eof_all\n" + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action eof_middle { + .section .rodata +7: + .string "eof_middle\n" + .text + movq $7b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action eof_out { + .section .rodata +8: + .string "eof_out\n" + .text + movq $8b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq erract_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "" +.L_inp_1: + .string "h" +.L_inp_2: + .string "x" +.L_inp_3: + .string "he" +.L_inp_4: + .string "hx" +.L_inp_5: + .string "hel" +.L_inp_6: + .string "hex" +.L_inp_7: + .string "hell" +.L_inp_8: + .string "helx" +.L_inp_9: + .string "hello" +.L_inp_10: + .string "hellx" +.L_inp_11: + .string "hello\n" +.L_inp_12: + .string "hellox" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + .quad .L_inp_9 + .quad .L_inp_10 + .quad .L_inp_11 + .quad .L_inp_12 + + .align 8 +inplen: + .quad 13 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/erract2_c.rl b/test/trans.d/case/erract2_c.rl new file mode 100644 index 00000000..be05030f --- /dev/null +++ b/test/trans.d/case/erract2_c.rl @@ -0,0 +1,95 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine erract; + + action err_start {printf( "%s", "err_start\n" ); +} + action err_all {printf( "%s", "err_all\n" ); +} + action err_middle {printf( "%s", "err_middle\n" ); +} + action err_out {printf( "%s", "err_out\n" ); +} + + action eof_start {printf( "%s", "eof_start\n" ); +} + action eof_all {printf( "%s", "eof_all\n" ); +} + action eof_middle {printf( "%s", "eof_middle\n" ); +} + action eof_out {printf( "%s", "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= erract_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +}; + +int inplen = 13; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/erract2_crack.rl b/test/trans.d/case/erract2_crack.rl new file mode 100644 index 00000000..0d419cad --- /dev/null +++ b/test/trans.d/case/erract2_crack.rl @@ -0,0 +1,80 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine erract; + + action err_start {cout.format( "err_start\n" ); +} + action err_all {cout.format( "err_all\n" ); +} + action err_middle {cout.format( "err_middle\n" ); +} + action err_out {cout.format( "err_out\n" ); +} + + action eof_start {cout.format( "eof_start\n" ); +} + action eof_all {cout.format( "eof_all\n" ); +} + action eof_middle {cout.format( "eof_middle\n" ); +} + action eof_out {cout.format( "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= erract_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "" ); + m( "h" ); + m( "x" ); + m( "he" ); + m( "hx" ); + m( "hel" ); + m( "hex" ); + m( "hell" ); + m( "helx" ); + m( "hello" ); + m( "hellx" ); + m( "hello\n" ); + m( "hellox" ); +} + +main(); diff --git a/test/trans.d/case/erract2_cs.rl b/test/trans.d/case/erract2_cs.rl new file mode 100644 index 00000000..3a264143 --- /dev/null +++ b/test/trans.d/case/erract2_cs.rl @@ -0,0 +1,91 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine erract; + + action err_start {Console.Write( "err_start\n" );} + action err_all {Console.Write( "err_all\n" );} + action err_middle {Console.Write( "err_middle\n" );} + action err_out {Console.Write( "err_out\n" );} + + action eof_start {Console.Write( "eof_start\n" );} + action eof_all {Console.Write( "eof_all\n" );} + action eof_middle {Console.Write( "eof_middle\n" );} + action eof_out {Console.Write( "eof_out\n" );} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= erract_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +}; + + +static readonly int inplen = 13; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/erract2_d.rl b/test/trans.d/case/erract2_d.rl new file mode 100644 index 00000000..a6ca6d77 --- /dev/null +++ b/test/trans.d/case/erract2_d.rl @@ -0,0 +1,91 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class erract +{ + + + +%%{ + machine erract; + + action err_start {printf( "%.*s", "err_start\n" );} + action err_all {printf( "%.*s", "err_all\n" );} + action err_middle {printf( "%.*s", "err_middle\n" );} + action err_out {printf( "%.*s", "err_out\n" );} + + action eof_start {printf( "%.*s", "eof_start\n" );} + action eof_all {printf( "%.*s", "eof_all\n" );} + action eof_middle {printf( "%.*s", "eof_middle\n" );} + action eof_out {printf( "%.*s", "eof_out\n" );} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= erract_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +]; + +int inplen = 13; + +} +int main() +{ + erract m = new erract(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/erract2_go.rl b/test/trans.d/case/erract2_go.rl new file mode 100644 index 00000000..c7ba0989 --- /dev/null +++ b/test/trans.d/case/erract2_go.rl @@ -0,0 +1,77 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine erract; + + action err_start {fmt.Print( "err_start\n" );} + action err_all {fmt.Print( "err_all\n" );} + action err_middle {fmt.Print( "err_middle\n" );} + action err_out {fmt.Print( "err_out\n" );} + + action eof_start {fmt.Print( "eof_start\n" );} + action eof_all {fmt.Print( "eof_all\n" );} + action eof_middle {fmt.Print( "eof_middle\n" );} + action eof_out {fmt.Print( "eof_out\n" );} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= erract_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/erract2_java.rl b/test/trans.d/case/erract2_java.rl new file mode 100644 index 00000000..edda48fa --- /dev/null +++ b/test/trans.d/case/erract2_java.rl @@ -0,0 +1,96 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class erract2_java +{ + + + +%%{ + machine erract; + + action err_start {System.out.print( "err_start\n" ); +} + action err_all {System.out.print( "err_all\n" ); +} + action err_middle {System.out.print( "err_middle\n" ); +} + action err_out {System.out.print( "err_out\n" ); +} + + action eof_start {System.out.print( "eof_start\n" ); +} + action eof_all {System.out.print( "eof_all\n" ); +} + action eof_middle {System.out.print( "eof_middle\n" ); +} + action eof_out {System.out.print( "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= erract_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +}; + +static final int inplen = 13; + +public static void main (String[] args) +{ + erract2_java machine = new erract2_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/erract2_julia.rl b/test/trans.d/case/erract2_julia.rl new file mode 100644 index 00000000..c8312cba --- /dev/null +++ b/test/trans.d/case/erract2_julia.rl @@ -0,0 +1,69 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine erract; + + action err_start {print( "err_start\n" ); +} + action err_all {print( "err_all\n" ); +} + action err_middle {print( "err_middle\n" ); +} + action err_out {print( "err_out\n" ); +} + + action eof_start {print( "eof_start\n" ); +} + action eof_all {print( "eof_all\n" ); +} + action eof_middle {print( "eof_middle\n" ); +} + action eof_out {print( "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= erract_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "" ); + m( "h" ); + m( "x" ); + m( "he" ); + m( "hx" ); + m( "hel" ); + m( "hex" ); + m( "hell" ); + m( "helx" ); + m( "hello" ); + m( "hellx" ); + m( "hello\n" ); + m( "hellox" ); diff --git a/test/trans.d/case/erract2_ocaml.rl b/test/trans.d/case/erract2_ocaml.rl new file mode 100644 index 00000000..dfeeaf5e --- /dev/null +++ b/test/trans.d/case/erract2_ocaml.rl @@ -0,0 +1,72 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine erract; + + action err_start {print_string( "err_start\n" ); +} + action err_all {print_string( "err_all\n" ); +} + action err_middle {print_string( "err_middle\n" ); +} + action err_out {print_string( "err_out\n" ); +} + + action eof_start {print_string( "eof_start\n" ); +} + action eof_all {print_string( "eof_all\n" ); +} + action eof_middle {print_string( "eof_middle\n" ); +} + action eof_out {print_string( "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= erract_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec ""; + exec "h"; + exec "x"; + exec "he"; + exec "hx"; + exec "hel"; + exec "hex"; + exec "hell"; + exec "helx"; + exec "hello"; + exec "hellx"; + exec "hello\n"; + exec "hellox"; + () +;; + diff --git a/test/trans.d/case/erract2_ruby.rl b/test/trans.d/case/erract2_ruby.rl new file mode 100644 index 00000000..0e65e2c0 --- /dev/null +++ b/test/trans.d/case/erract2_ruby.rl @@ -0,0 +1,77 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine erract; + + action err_start {print( "err_start\n" ); +} + action err_all {print( "err_all\n" ); +} + action err_middle {print( "err_middle\n" ); +} + action err_out {print( "err_out\n" ); +} + + action eof_start {print( "eof_start\n" ); +} + action eof_all {print( "eof_all\n" ); +} + action eof_middle {print( "eof_middle\n" ); +} + action eof_out {print( "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= erract_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"", +"h", +"x", +"he", +"hx", +"hel", +"hex", +"hell", +"helx", +"hello", +"hellx", +"hello\n", +"hellox", +] + +inplen = 13 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/erract2_rust.rl b/test/trans.d/case/erract2_rust.rl new file mode 100644 index 00000000..e541df3c --- /dev/null +++ b/test/trans.d/case/erract2_rust.rl @@ -0,0 +1,76 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine erract; + + action err_start {print!( "{}", "err_start\n" ); +} + action err_all {print!( "{}", "err_all\n" ); +} + action err_middle {print!( "{}", "err_middle\n" ); +} + action err_out {print!( "{}", "err_out\n" ); +} + + action eof_start {print!( "{}", "eof_start\n" ); +} + action eof_all {print!( "{}", "eof_all\n" ); +} + action eof_middle {print!( "{}", "eof_middle\n" ); +} + action eof_out {print!( "{}", "eof_out\n" ); +} + + main := ( 'hello' + >err err_start $err err_all <>err err_middle %err err_out + >eof eof_start $eof eof_all <>eof eof_middle %eof eof_out + ) '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= erract_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "".to_string() ); } + unsafe { m( "h".to_string() ); } + unsafe { m( "x".to_string() ); } + unsafe { m( "he".to_string() ); } + unsafe { m( "hx".to_string() ); } + unsafe { m( "hel".to_string() ); } + unsafe { m( "hex".to_string() ); } + unsafe { m( "hell".to_string() ); } + unsafe { m( "helx".to_string() ); } + unsafe { m( "hello".to_string() ); } + unsafe { m( "hellx".to_string() ); } + unsafe { m( "hello\n".to_string() ); } + unsafe { m( "hellox".to_string() ); } +} + diff --git a/test/trans.d/case/goto1.rl b/test/trans.d/case/goto1.rl new file mode 100644 index 00000000..4b9385bd --- /dev/null +++ b/test/trans.d/case/goto1.rl @@ -0,0 +1,37 @@ +/* + * @LANG: indep + * @PROHIBIT_LANGUAGES: ruby ocaml + */ + +int target; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + target = fentry(main); + fgoto *target; + }; + + two := 'two' @{ + print_str "two\n"; + target = fentry(main); + fgoto *target; + }; + + main := + '1' @{ target = fentry(one); fgoto *target; } + | '2' @{ target = fentry(two); fgoto *target; } + | '\n'; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/goto1_asm.rl b/test/trans.d/case/goto1_asm.rl new file mode 100644 index 00000000..f92f45a6 --- /dev/null +++ b/test/trans.d/case/goto1_asm.rl @@ -0,0 +1,187 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm target,8,8 + .text + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +}; + + main := + '1' @{ + movq $fentry(one), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +} + | '2' @{ + movq $fentry(two), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +} + | '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq goto1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/goto1_c.rl b/test/trans.d/case/goto1_c.rl new file mode 100644 index 00000000..729c5c5a --- /dev/null +++ b/test/trans.d/case/goto1_c.rl @@ -0,0 +1,75 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int target ; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +target = fentry(main); +fgoto *target;}; + + two := 'two' @{printf( "%s", "two\n" ); +target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= goto1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/goto1_crack.rl b/test/trans.d/case/goto1_crack.rl new file mode 100644 index 00000000..6a124918 --- /dev/null +++ b/test/trans.d/case/goto1_crack.rl @@ -0,0 +1,60 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int target; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +target = fentry(main); +fgoto *target;}; + + two := 'two' @{cout.format( "two\n" ); +target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= goto1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/goto1_cs.rl b/test/trans.d/case/goto1_cs.rl new file mode 100644 index 00000000..bf95503a --- /dev/null +++ b/test/trans.d/case/goto1_cs.rl @@ -0,0 +1,78 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int target; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );target = fentry(main); +fgoto *target;}; + + two := 'two' @{Console.Write( "two\n" );target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= goto1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/goto1_d.rl b/test/trans.d/case/goto1_d.rl new file mode 100644 index 00000000..dc7979cd --- /dev/null +++ b/test/trans.d/case/goto1_d.rl @@ -0,0 +1,77 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class goto1 +{ +int target; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main); +fgoto *target;}; + + two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= goto1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + goto1 m = new goto1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/goto1_go.rl b/test/trans.d/case/goto1_go.rl new file mode 100644 index 00000000..ba6df377 --- /dev/null +++ b/test/trans.d/case/goto1_go.rl @@ -0,0 +1,69 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var target int ; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );target = fentry(main); +fgoto *target; + +}; + + two := 'two' @{fmt.Print( "two\n" );target = fentry(main); +fgoto *target; + +}; + + main := + '1' @{target = fentry(one); +fgoto *target; +} + | '2' @{target = fentry(two); +fgoto *target; +} + | '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= goto1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/goto1_java.rl b/test/trans.d/case/goto1_java.rl new file mode 100644 index 00000000..668faaf7 --- /dev/null +++ b/test/trans.d/case/goto1_java.rl @@ -0,0 +1,76 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class goto1_java +{ +int target ; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +target = fentry(main); +fgoto *target;}; + + two := 'two' @{System.out.print( "two\n" ); +target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= goto1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + goto1_java machine = new goto1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/goto1_julia.rl b/test/trans.d/case/goto1_julia.rl new file mode 100644 index 00000000..33bc2a6d --- /dev/null +++ b/test/trans.d/case/goto1_julia.rl @@ -0,0 +1,50 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +target = fentry(main); +fgoto *target;}; + + two := 'two' @{print( "two\n" ); +target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +target = 0; + + %% write init; + %% write exec; + + if ( cs >= goto1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/goto1_rust.rl b/test/trans.d/case/goto1_rust.rl new file mode 100644 index 00000000..ac7e4ee8 --- /dev/null +++ b/test/trans.d/case/goto1_rust.rl @@ -0,0 +1,57 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut target : i32 = 0; + +%%{ + machine goto1; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +target = fentry(main); +fgoto *target;}; + + two := 'two' @{print!( "{}", "two\n" ); +target = fentry(main); +fgoto *target;}; + + main := + '1' @{target = fentry(one); +fgoto *target;} + | '2' @{target = fentry(two); +fgoto *target;} + | '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= goto1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/gotocallret1.rl b/test/trans.d/case/gotocallret1.rl new file mode 100644 index 00000000..91804725 --- /dev/null +++ b/test/trans.d/case/gotocallret1.rl @@ -0,0 +1,117 @@ +/* + * @LANG: indep + * @PROHIBIT_LANGUAGES: ruby ocaml + * @PROHIBIT_FEATFLAGS: --var-backend + * @NEEDS_EOF: yes + */ + +/* + * Demonstrate the use of goto, call and return. This machine expects either a + * lower case char or a digit as a command then a space followed by the command + * arg. If the command is a char, then the arg must be an a string of chars. + * If the command is a digit, then the arg must be a string of digits. This + * choice is determined by action code, rather than though transition + * desitinations. + */ + +char comm; +int top; +int stack[32]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction { fentry(garble_line); } + + action err_garbling_line { print_str "error: garbling line\n"; } + action goto_main { fgoto main; } + action recovery_failed { print_str "error: failed to recover\n"; } + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold; fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg { + if ( comm >= 'a' ) { + fcall alp_comm; + } else { + fcall dig_comm; + } + } + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n' + ) @{print_str "correct command\n";}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + +##### INPUT ##### +"lkajsdf\n" +"2134\n" +"(\n" +"\n" +"*234234()0909 092 -234aslkf09`1 11\n" +"1\n" +"909\n" +"1 a\n" +"11 1\n" +"a 1\n" +"aa a\n" +"1 1\n" +"1 123456\n" +"a a\n" +"a abcdef\n" +"h" +"a aa1" +##### OUTPUT ##### +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +correct command +ACCEPT +correct command +ACCEPT +correct command +ACCEPT +correct command +ACCEPT +error: failed to recover +FAIL +error: garbling line +error: failed to recover +FAIL diff --git a/test/trans.d/case/gotocallret1_asm.rl b/test/trans.d/case/gotocallret1_asm.rl new file mode 100644 index 00000000..f43b3760 --- /dev/null +++ b/test/trans.d/case/gotocallret1_asm.rl @@ -0,0 +1,280 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm comm,8,8 + .text + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction { + movq $fentry(garble_line), %rax + pushq %rax + popq %rax + +} + + action err_garbling_line { + .section .rodata +1: + .string "error: garbling line\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action goto_main { + fgoto main; + +} + action recovery_failed { + .section .rodata +2: + .string "error: failed to recover\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return { + fhold; +fret; + +} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg { + movq comm (%rip), %rax + pushq %rax + movq $97, %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setge %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 3f +fcall alp_comm; + + jmp 4f +3: +fcall dig_comm; + +4: + +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{ + movsbq (%r12), %rax + pushq %rax + popq %rax + movq %rax, comm (%rip) + +} ' ' @comm_arg '\n' + ) @{ + .section .rodata +5: + .string "correct command\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{ + fhold; +fgoto garble_line; + +}; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq GotoCallRet_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "lkajsdf\n" +.L_inp_1: + .string "2134\n" +.L_inp_2: + .string "(\n" +.L_inp_3: + .string "\n" +.L_inp_4: + .string "*234234()0909 092 -234aslkf09`1 11\n" +.L_inp_5: + .string "1\n" +.L_inp_6: + .string "909\n" +.L_inp_7: + .string "1 a\n" +.L_inp_8: + .string "11 1\n" +.L_inp_9: + .string "a 1\n" +.L_inp_10: + .string "aa a\n" +.L_inp_11: + .string "1 1\n" +.L_inp_12: + .string "1 123456\n" +.L_inp_13: + .string "a a\n" +.L_inp_14: + .string "a abcdef\n" +.L_inp_15: + .string "h" +.L_inp_16: + .string "a aa1" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + .quad .L_inp_9 + .quad .L_inp_10 + .quad .L_inp_11 + .quad .L_inp_12 + .quad .L_inp_13 + .quad .L_inp_14 + .quad .L_inp_15 + .quad .L_inp_16 + + .align 8 +inplen: + .quad 17 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/gotocallret1_c.rl b/test/trans.d/case/gotocallret1_c.rl new file mode 100644 index 00000000..6759cc15 --- /dev/null +++ b/test/trans.d/case/gotocallret1_c.rl @@ -0,0 +1,122 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char comm ; +int top ; +int stack [32]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {printf( "%s", "error: garbling line\n" ); +} + action goto_main {fgoto main;} + action recovery_failed {printf( "%s", "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{printf( "%s", "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +int inplen = 17; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret1_crack.rl b/test/trans.d/case/gotocallret1_crack.rl new file mode 100644 index 00000000..1f1f1aa2 --- /dev/null +++ b/test/trans.d/case/gotocallret1_crack.rl @@ -0,0 +1,107 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +byte comm; +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {cout.format( "error: garbling line\n" ); +} + action goto_main {fgoto main;} + action recovery_failed {cout.format( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{cout.format( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "lkajsdf\n" ); + m( "2134\n" ); + m( "(\n" ); + m( "\n" ); + m( "*234234()0909 092 -234aslkf09`1 11\n" ); + m( "1\n" ); + m( "909\n" ); + m( "1 a\n" ); + m( "11 1\n" ); + m( "a 1\n" ); + m( "aa a\n" ); + m( "1 1\n" ); + m( "1 123456\n" ); + m( "a a\n" ); + m( "a abcdef\n" ); + m( "h" ); + m( "a aa1" ); +} + +main(); diff --git a/test/trans.d/case/gotocallret1_cs.rl b/test/trans.d/case/gotocallret1_cs.rl new file mode 100644 index 00000000..37a005e8 --- /dev/null +++ b/test/trans.d/case/gotocallret1_cs.rl @@ -0,0 +1,123 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +char comm; +int top; +int [] stack = new int [32]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {Console.Write( "error: garbling line\n" );} + action goto_main {fgoto main;} + action recovery_failed {Console.Write( "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{Console.Write( "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + + +static readonly int inplen = 17; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/gotocallret1_d.rl b/test/trans.d/case/gotocallret1_d.rl new file mode 100644 index 00000000..ba4f57e2 --- /dev/null +++ b/test/trans.d/case/gotocallret1_d.rl @@ -0,0 +1,123 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class GotoCallRet +{ +char comm; +int top; +int stack[32]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {printf( "%.*s", "error: garbling line\n" );} + action goto_main {fgoto main;} + action recovery_failed {printf( "%.*s", "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{printf( "%.*s", "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +]; + +int inplen = 17; + +} +int main() +{ + GotoCallRet m = new GotoCallRet(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret1_go.rl b/test/trans.d/case/gotocallret1_go.rl new file mode 100644 index 00000000..5806cd76 --- /dev/null +++ b/test/trans.d/case/gotocallret1_go.rl @@ -0,0 +1,116 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var comm byte ; +var top int ; +var stack [32] int ; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {fmt.Print( "error: garbling line\n" );} + action goto_main {fgoto main; +} + action recovery_failed {fmt.Print( "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold; +fret; +} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) { + fcall alp_comm; + + +} else { + fcall dig_comm; + + +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{fmt.Print( "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold; +fgoto garble_line; +}; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= GotoCallRet_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/gotocallret1_java.rl b/test/trans.d/case/gotocallret1_java.rl new file mode 100644 index 00000000..343ade95 --- /dev/null +++ b/test/trans.d/case/gotocallret1_java.rl @@ -0,0 +1,123 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class gotocallret1_java +{ +char comm ; +int top ; +int stack [] = new int[32]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {System.out.print( "error: garbling line\n" ); +} + action goto_main {fgoto main;} + action recovery_failed {System.out.print( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{System.out.print( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +static final int inplen = 17; + +public static void main (String[] args) +{ + gotocallret1_java machine = new gotocallret1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/gotocallret1_julia.rl b/test/trans.d/case/gotocallret1_julia.rl new file mode 100644 index 00000000..3b7c980a --- /dev/null +++ b/test/trans.d/case/gotocallret1_julia.rl @@ -0,0 +1,94 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {print( "error: garbling line\n" ); +} + action goto_main {fgoto main;} + action recovery_failed {print( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) + fcall alp_comm; +else + fcall dig_comm; +end +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{print( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +comm = 0; +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "lkajsdf\n" ); + m( "2134\n" ); + m( "(\n" ); + m( "\n" ); + m( "*234234()0909 092 -234aslkf09`1 11\n" ); + m( "1\n" ); + m( "909\n" ); + m( "1 a\n" ); + m( "11 1\n" ); + m( "a 1\n" ); + m( "aa a\n" ); + m( "1 1\n" ); + m( "1 123456\n" ); + m( "a a\n" ); + m( "a abcdef\n" ); + m( "h" ); + m( "a aa1" ); diff --git a/test/trans.d/case/gotocallret1_rust.rl b/test/trans.d/case/gotocallret1_rust.rl new file mode 100644 index 00000000..308d9eae --- /dev/null +++ b/test/trans.d/case/gotocallret1_rust.rl @@ -0,0 +1,103 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut comm : u8 = 0; +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine GotoCallRet; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {print!( "{}", "error: garbling line\n" ); +} + action goto_main {fgoto main;} + action recovery_failed {print!( "{}", "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 'a' ) +{ + fcall alp_comm; +} +else { + fcall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg '\n' + ) @{print!( "{}", "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fgoto garble_line;}; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "lkajsdf\n".to_string() ); } + unsafe { m( "2134\n".to_string() ); } + unsafe { m( "(\n".to_string() ); } + unsafe { m( "\n".to_string() ); } + unsafe { m( "*234234()0909 092 -234aslkf09`1 11\n".to_string() ); } + unsafe { m( "1\n".to_string() ); } + unsafe { m( "909\n".to_string() ); } + unsafe { m( "1 a\n".to_string() ); } + unsafe { m( "11 1\n".to_string() ); } + unsafe { m( "a 1\n".to_string() ); } + unsafe { m( "aa a\n".to_string() ); } + unsafe { m( "1 1\n".to_string() ); } + unsafe { m( "1 123456\n".to_string() ); } + unsafe { m( "a a\n".to_string() ); } + unsafe { m( "a abcdef\n".to_string() ); } + unsafe { m( "h".to_string() ); } + unsafe { m( "a aa1".to_string() ); } +} + diff --git a/test/trans.d/case/gotocallret2.rl b/test/trans.d/case/gotocallret2.rl new file mode 100644 index 00000000..31dd13d7 --- /dev/null +++ b/test/trans.d/case/gotocallret2.rl @@ -0,0 +1,78 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + * @PROHIBIT_LANGUAGES: ruby ocaml + * @PROHIBIT_FEATFLAGS: --var-backend + */ + +char comm; +int top; +int stack[32]; +ptr ts; +ptr te; +int act; +int val; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{ + print_str "handle "; + fhold; + if ( val == 1 ) { fnext *fentry(one); } + if ( val == 2 ) { fnext *fentry(two); } + if ( val == 3 ) { fnext main; } + }; + + one := |* + '{' => { print_str "{ "; fcall *fentry(one); }; + "[" => { print_str "[ "; fcall *fentry(two); }; + "}" sp* => { print_str "} "; fret; }; + [a-z]+ => { print_str "word "; val = 1; fgoto *fentry(handle); }; + ' ' => { print_str "space "; }; + *|; + + two := |* + '{' => { print_str "{ "; fcall *fentry(one); }; + "[" => { print_str "[ "; fcall *fentry(two); }; + ']' sp* => { print_str "] "; fret; }; + [a-z]+ => { print_str "word "; val = 2; fgoto *fentry(handle); }; + ' ' => { print_str "space "; }; + *|; + + main := |* + '{' => { print_str "{ "; fcall one; }; + "[" => { print_str "[ "; fcall two; }; + [a-z]+ => { print_str "word "; val = 3; fgoto handle; }; + [a-z] ' foil' => { print_str "this is the foil";}; + ' ' => { print_str "space "; }; + '\n'; + *|; +}%% + +##### INPUT ##### +"{a{b[c d]d}c}\n" +"[a{b[c d]d}c}\n" +"[a[b]c]d{ef{g{h}i}j}l\n" +"{{[]}}\n" +"a b c\n" +"{a b c}\n" +"[a b c]\n" +"{]\n" +"{{}\n" +"[[[[[[]]]]]]\n" +"[[[[[[]]}]]]\n" +##### OUTPUT ##### +{ word handle { word handle [ word handle space word handle ] word handle } word handle } ACCEPT +[ word handle { word handle [ word handle space word handle ] word handle } word handle FAIL +[ word handle [ word handle ] word handle ] word handle { word handle { word handle { word handle } word handle } word handle } word handle ACCEPT +{ { [ ] } } ACCEPT +word handle space word handle space word handle ACCEPT +{ word handle space word handle space word handle } ACCEPT +[ word handle space word handle space word handle ] ACCEPT +{ FAIL +{ { } FAIL +[ [ [ [ [ [ ] ] ] ] ] ] ACCEPT +[ [ [ [ [ [ ] ] FAIL diff --git a/test/trans.d/case/gotocallret2_asm.rl b/test/trans.d/case/gotocallret2_asm.rl new file mode 100644 index 00000000..47253b18 --- /dev/null +++ b/test/trans.d/case/gotocallret2_asm.rl @@ -0,0 +1,484 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm comm,8,8 + .text + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm val,8,8 + .text + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{ + .section .rodata +1: + .string "handle " + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fhold; + + movq val (%rip), %rax + pushq %rax + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 2f + movq $fentry(one), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; +2: + movq val (%rip), %rax + pushq %rax + movq $2 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 4f + movq $fentry(two), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; +4: + movq val (%rip), %rax + pushq %rax + movq $3 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 6f +fnext main; +6: + +}; + + one := |* + '{' => { + .section .rodata +8: + .string "{ " + .text + movq $8b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(one), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +}; + "[" => { + .section .rodata +9: + .string "[ " + .text + movq $9b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(two), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +}; + "}" sp* => { + .section .rodata +10: + .string "} " + .text + movq $10b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fret; + +}; + [a-z]+ => { + .section .rodata +11: + .string "word " + .text + movq $11b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $1, %rax + pushq %rax + popq %rax + movq %rax, val (%rip) + movq $fentry(handle), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +}; + ' ' => { + .section .rodata +12: + .string "space " + .text + movq $12b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; + + two := |* + '{' => { + .section .rodata +13: + .string "{ " + .text + movq $13b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(one), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +}; + "[" => { + .section .rodata +14: + .string "[ " + .text + movq $14b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(two), %rax + pushq %rax +movq $0, %rax +popq %rcx +fcall * %rcx; + +}; + ']' sp* => { + .section .rodata +15: + .string "] " + .text + movq $15b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fret; + +}; + [a-z]+ => { + .section .rodata +16: + .string "word " + .text + movq $16b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $2, %rax + pushq %rax + popq %rax + movq %rax, val (%rip) + movq $fentry(handle), %rax + pushq %rax +movq $0, %rax +popq %rcx +fgoto * %rcx; + +}; + ' ' => { + .section .rodata +17: + .string "space " + .text + movq $17b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; + + main := |* + '{' => { + .section .rodata +18: + .string "{ " + .text + movq $18b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fcall one; + +}; + "[" => { + .section .rodata +19: + .string "[ " + .text + movq $19b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fcall two; + +}; + [a-z]+ => { + .section .rodata +20: + .string "word " + .text + movq $20b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $3, %rax + pushq %rax + popq %rax + movq %rax, val (%rip) +fgoto handle; + +}; + [a-z] ' foil' => { + .section .rodata +21: + .string "this is the foil" + .text + movq $21b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + ' ' => { + .section .rodata +22: + .string "space " + .text + movq $22b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '\n'; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq GotoCallRet_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "{a{b[c d]d}c}\n" +.L_inp_1: + .string "[a{b[c d]d}c}\n" +.L_inp_2: + .string "[a[b]c]d{ef{g{h}i}j}l\n" +.L_inp_3: + .string "{{[]}}\n" +.L_inp_4: + .string "a b c\n" +.L_inp_5: + .string "{a b c}\n" +.L_inp_6: + .string "[a b c]\n" +.L_inp_7: + .string "{]\n" +.L_inp_8: + .string "{{}\n" +.L_inp_9: + .string "[[[[[[]]]]]]\n" +.L_inp_10: + .string "[[[[[[]]}]]]\n" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + .quad .L_inp_9 + .quad .L_inp_10 + + .align 8 +inplen: + .quad 11 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/gotocallret2_c.rl b/test/trans.d/case/gotocallret2_c.rl new file mode 100644 index 00000000..26a54187 --- /dev/null +++ b/test/trans.d/case/gotocallret2_c.rl @@ -0,0 +1,135 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char comm ; +int top ; +int stack [32]; +char * ts ; +char * te ; +int act ; +int val ; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{printf( "%s", "handle " ); +fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {printf( "%s", "{ " ); +fcall *fentry(one);}; + "[" => {printf( "%s", "[ " ); +fcall *fentry(two);}; + "}" sp* => {printf( "%s", "} " ); +fret;}; + [a-z]+ => {printf( "%s", "word " ); +val = 1; +fgoto *fentry(handle);}; + ' ' => {printf( "%s", "space " ); +}; + *|; + + two := |* + '{' => {printf( "%s", "{ " ); +fcall *fentry(one);}; + "[" => {printf( "%s", "[ " ); +fcall *fentry(two);}; + ']' sp* => {printf( "%s", "] " ); +fret;}; + [a-z]+ => {printf( "%s", "word " ); +val = 2; +fgoto *fentry(handle);}; + ' ' => {printf( "%s", "space " ); +}; + *|; + + main := |* + '{' => {printf( "%s", "{ " ); +fcall one;}; + "[" => {printf( "%s", "[ " ); +fcall two;}; + [a-z]+ => {printf( "%s", "word " ); +val = 3; +fgoto handle;}; + [a-z] ' foil' => {printf( "%s", "this is the foil" ); +}; + ' ' => {printf( "%s", "space " ); +}; + '\n'; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"{a{b[c d]d}c}\n", +"[a{b[c d]d}c}\n", +"[a[b]c]d{ef{g{h}i}j}l\n", +"{{[]}}\n", +"a b c\n", +"{a b c}\n", +"[a b c]\n", +"{]\n", +"{{}\n", +"[[[[[[]]]]]]\n", +"[[[[[[]]}]]]\n", +}; + +int inplen = 11; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret2_crack.rl b/test/trans.d/case/gotocallret2_crack.rl new file mode 100644 index 00000000..23e22f48 --- /dev/null +++ b/test/trans.d/case/gotocallret2_crack.rl @@ -0,0 +1,122 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +byte comm; +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +int + ts; +int + te; +int act; +int val; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{cout.format( "handle " ); +fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {cout.format( "{ " ); +fcall *fentry(one);}; + "[" => {cout.format( "[ " ); +fcall *fentry(two);}; + "}" sp* => {cout.format( "} " ); +fret;}; + [a-z]+ => {cout.format( "word " ); +val = 1; +fgoto *fentry(handle);}; + ' ' => {cout.format( "space " ); +}; + *|; + + two := |* + '{' => {cout.format( "{ " ); +fcall *fentry(one);}; + "[" => {cout.format( "[ " ); +fcall *fentry(two);}; + ']' sp* => {cout.format( "] " ); +fret;}; + [a-z]+ => {cout.format( "word " ); +val = 2; +fgoto *fentry(handle);}; + ' ' => {cout.format( "space " ); +}; + *|; + + main := |* + '{' => {cout.format( "{ " ); +fcall one;}; + "[" => {cout.format( "[ " ); +fcall two;}; + [a-z]+ => {cout.format( "word " ); +val = 3; +fgoto handle;}; + [a-z] ' foil' => {cout.format( "this is the foil" ); +}; + ' ' => {cout.format( "space " ); +}; + '\n'; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "{a{b[c d]d}c}\n" ); + m( "[a{b[c d]d}c}\n" ); + m( "[a[b]c]d{ef{g{h}i}j}l\n" ); + m( "{{[]}}\n" ); + m( "a b c\n" ); + m( "{a b c}\n" ); + m( "[a b c]\n" ); + m( "{]\n" ); + m( "{{}\n" ); + m( "[[[[[[]]]]]]\n" ); + m( "[[[[[[]]}]]]\n" ); +} + +main(); diff --git a/test/trans.d/case/gotocallret2_cs.rl b/test/trans.d/case/gotocallret2_cs.rl new file mode 100644 index 00000000..dc806d0a --- /dev/null +++ b/test/trans.d/case/gotocallret2_cs.rl @@ -0,0 +1,123 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +char comm; +int top; +int [] stack = new int [32]; +int ts; +int te; +int act; +int val; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{Console.Write( "handle " );fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {Console.Write( "{ " );fcall *fentry(one);}; + "[" => {Console.Write( "[ " );fcall *fentry(two);}; + "}" sp* => {Console.Write( "} " );fret;}; + [a-z]+ => {Console.Write( "word " );val = 1; +fgoto *fentry(handle);}; + ' ' => {Console.Write( "space " );}; + *|; + + two := |* + '{' => {Console.Write( "{ " );fcall *fentry(one);}; + "[" => {Console.Write( "[ " );fcall *fentry(two);}; + ']' sp* => {Console.Write( "] " );fret;}; + [a-z]+ => {Console.Write( "word " );val = 2; +fgoto *fentry(handle);}; + ' ' => {Console.Write( "space " );}; + *|; + + main := |* + '{' => {Console.Write( "{ " );fcall one;}; + "[" => {Console.Write( "[ " );fcall two;}; + [a-z]+ => {Console.Write( "word " );val = 3; +fgoto handle;}; + [a-z] ' foil' => {Console.Write( "this is the foil" );}; + ' ' => {Console.Write( "space " );}; + '\n'; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"{a{b[c d]d}c}\n", +"[a{b[c d]d}c}\n", +"[a[b]c]d{ef{g{h}i}j}l\n", +"{{[]}}\n", +"a b c\n", +"{a b c}\n", +"[a b c]\n", +"{]\n", +"{{}\n", +"[[[[[[]]]]]]\n", +"[[[[[[]]}]]]\n", +}; + + +static readonly int inplen = 11; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/gotocallret2_d.rl b/test/trans.d/case/gotocallret2_d.rl new file mode 100644 index 00000000..1aa67996 --- /dev/null +++ b/test/trans.d/case/gotocallret2_d.rl @@ -0,0 +1,123 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class GotoCallRet +{ +char comm; +int top; +int stack[32]; +const(char) * ts; +const(char) * te; +int act; +int val; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{printf( "%.*s", "handle " );fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {printf( "%.*s", "{ " );fcall *fentry(one);}; + "[" => {printf( "%.*s", "[ " );fcall *fentry(two);}; + "}" sp* => {printf( "%.*s", "} " );fret;}; + [a-z]+ => {printf( "%.*s", "word " );val = 1; +fgoto *fentry(handle);}; + ' ' => {printf( "%.*s", "space " );}; + *|; + + two := |* + '{' => {printf( "%.*s", "{ " );fcall *fentry(one);}; + "[" => {printf( "%.*s", "[ " );fcall *fentry(two);}; + ']' sp* => {printf( "%.*s", "] " );fret;}; + [a-z]+ => {printf( "%.*s", "word " );val = 2; +fgoto *fentry(handle);}; + ' ' => {printf( "%.*s", "space " );}; + *|; + + main := |* + '{' => {printf( "%.*s", "{ " );fcall one;}; + "[" => {printf( "%.*s", "[ " );fcall two;}; + [a-z]+ => {printf( "%.*s", "word " );val = 3; +fgoto handle;}; + [a-z] ' foil' => {printf( "%.*s", "this is the foil" );}; + ' ' => {printf( "%.*s", "space " );}; + '\n'; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"{a{b[c d]d}c}\n", +"[a{b[c d]d}c}\n", +"[a[b]c]d{ef{g{h}i}j}l\n", +"{{[]}}\n", +"a b c\n", +"{a b c}\n", +"[a b c]\n", +"{]\n", +"{{}\n", +"[[[[[[]]]]]]\n", +"[[[[[[]]}]]]\n", +]; + +int inplen = 11; + +} +int main() +{ + GotoCallRet m = new GotoCallRet(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret2_go.rl b/test/trans.d/case/gotocallret2_go.rl new file mode 100644 index 00000000..0a13ab3f --- /dev/null +++ b/test/trans.d/case/gotocallret2_go.rl @@ -0,0 +1,122 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var comm byte ; +var top int ; +var stack [32] int ; +var ts int ; +var te int ; +var act int ; +var val int ; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{fmt.Print( "handle " );fhold; + +if ( val == 1 ) { + fnext *fentry(one); + +} +if ( val == 2 ) { + fnext *fentry(two); + +} +if ( val == 3 ) { + fnext main; + +} +}; + + one := |* + '{' => {fmt.Print( "{ " );fcall *fentry(one); +}; + "[" => {fmt.Print( "[ " );fcall *fentry(two); +}; + "}" sp* => {fmt.Print( "} " );fret; +}; + [a-z]+ => {fmt.Print( "word " );val = 1; +fgoto *fentry(handle); +}; + ' ' => {fmt.Print( "space " );}; + *|; + + two := |* + '{' => {fmt.Print( "{ " );fcall *fentry(one); +}; + "[" => {fmt.Print( "[ " );fcall *fentry(two); +}; + ']' sp* => {fmt.Print( "] " );fret; +}; + [a-z]+ => {fmt.Print( "word " );val = 2; +fgoto *fentry(handle); +}; + ' ' => {fmt.Print( "space " );}; + *|; + + main := |* + '{' => {fmt.Print( "{ " );fcall one; +}; + "[" => {fmt.Print( "[ " );fcall two; +}; + [a-z]+ => {fmt.Print( "word " );val = 3; +fgoto handle; +}; + [a-z] ' foil' => {fmt.Print( "this is the foil" );}; + ' ' => {fmt.Print( "space " );}; + '\n'; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= GotoCallRet_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"{a{b[c d]d}c}\n", +"[a{b[c d]d}c}\n", +"[a[b]c]d{ef{g{h}i}j}l\n", +"{{[]}}\n", +"a b c\n", +"{a b c}\n", +"[a b c]\n", +"{]\n", +"{{}\n", +"[[[[[[]]]]]]\n", +"[[[[[[]]}]]]\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/gotocallret2_java.rl b/test/trans.d/case/gotocallret2_java.rl new file mode 100644 index 00000000..3022924e --- /dev/null +++ b/test/trans.d/case/gotocallret2_java.rl @@ -0,0 +1,138 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class gotocallret2_java +{ +char comm ; +int top ; +int stack [] = new int[32]; +int + ts ; +int + te ; +int act ; +int val ; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{System.out.print( "handle " ); +fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {System.out.print( "{ " ); +fcall *fentry(one);}; + "[" => {System.out.print( "[ " ); +fcall *fentry(two);}; + "}" sp* => {System.out.print( "} " ); +fret;}; + [a-z]+ => {System.out.print( "word " ); +val = 1; +fgoto *fentry(handle);}; + ' ' => {System.out.print( "space " ); +}; + *|; + + two := |* + '{' => {System.out.print( "{ " ); +fcall *fentry(one);}; + "[" => {System.out.print( "[ " ); +fcall *fentry(two);}; + ']' sp* => {System.out.print( "] " ); +fret;}; + [a-z]+ => {System.out.print( "word " ); +val = 2; +fgoto *fentry(handle);}; + ' ' => {System.out.print( "space " ); +}; + *|; + + main := |* + '{' => {System.out.print( "{ " ); +fcall one;}; + "[" => {System.out.print( "[ " ); +fcall two;}; + [a-z]+ => {System.out.print( "word " ); +val = 3; +fgoto handle;}; + [a-z] ' foil' => {System.out.print( "this is the foil" ); +}; + ' ' => {System.out.print( "space " ); +}; + '\n'; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= GotoCallRet_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"{a{b[c d]d}c}\n", +"[a{b[c d]d}c}\n", +"[a[b]c]d{ef{g{h}i}j}l\n", +"{{[]}}\n", +"a b c\n", +"{a b c}\n", +"[a b c]\n", +"{]\n", +"{{}\n", +"[[[[[[]]]]]]\n", +"[[[[[[]]}]]]\n", +}; + +static final int inplen = 11; + +public static void main (String[] args) +{ + gotocallret2_java machine = new gotocallret2_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/gotocallret2_julia.rl b/test/trans.d/case/gotocallret2_julia.rl new file mode 100644 index 00000000..24907e11 --- /dev/null +++ b/test/trans.d/case/gotocallret2_julia.rl @@ -0,0 +1,106 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{print( "handle " ); +fhold;if ( val == 1 ) + fnext *fentry(one); +end +if ( val == 2 ) + fnext *fentry(two); +end +if ( val == 3 ) + fnext main; +end +}; + + one := |* + '{' => {print( "{ " ); +fcall *fentry(one);}; + "[" => {print( "[ " ); +fcall *fentry(two);}; + "}" sp* => {print( "} " ); +fret;}; + [a-z]+ => {print( "word " ); +val = 1; +fgoto *fentry(handle);}; + ' ' => {print( "space " ); +}; + *|; + + two := |* + '{' => {print( "{ " ); +fcall *fentry(one);}; + "[" => {print( "[ " ); +fcall *fentry(two);}; + ']' sp* => {print( "] " ); +fret;}; + [a-z]+ => {print( "word " ); +val = 2; +fgoto *fentry(handle);}; + ' ' => {print( "space " ); +}; + *|; + + main := |* + '{' => {print( "{ " ); +fcall one;}; + "[" => {print( "[ " ); +fcall two;}; + [a-z]+ => {print( "word " ); +val = 3; +fgoto handle;}; + [a-z] ' foil' => {print( "this is the foil" ); +}; + ' ' => {print( "space " ); +}; + '\n'; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +comm = 0; +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +ts = 0; +te = 0; +act = 0; +val = 0; + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "{a{b[c d]d}c}\n" ); + m( "[a{b[c d]d}c}\n" ); + m( "[a[b]c]d{ef{g{h}i}j}l\n" ); + m( "{{[]}}\n" ); + m( "a b c\n" ); + m( "{a b c}\n" ); + m( "[a b c]\n" ); + m( "{]\n" ); + m( "{{}\n" ); + m( "[[[[[[]]]]]]\n" ); + m( "[[[[[[]]}]]]\n" ); diff --git a/test/trans.d/case/gotocallret2_rust.rl b/test/trans.d/case/gotocallret2_rust.rl new file mode 100644 index 00000000..4ff56f43 --- /dev/null +++ b/test/trans.d/case/gotocallret2_rust.rl @@ -0,0 +1,118 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut comm : u8 = 0; +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut val : i32 = 0; + +%%{ + machine GotoCallRet; + + sp = ' '; + + handle := any @{print!( "{}", "handle " ); +fhold;if ( val == 1 ) +{ + fnext *fentry(one); +} +if ( val == 2 ) +{ + fnext *fentry(two); +} +if ( val == 3 ) +{ + fnext main; +} +}; + + one := |* + '{' => {print!( "{}", "{ " ); +fcall *fentry(one);}; + "[" => {print!( "{}", "[ " ); +fcall *fentry(two);}; + "}" sp* => {print!( "{}", "} " ); +fret;}; + [a-z]+ => {print!( "{}", "word " ); +val = 1; +fgoto *fentry(handle);}; + ' ' => {print!( "{}", "space " ); +}; + *|; + + two := |* + '{' => {print!( "{}", "{ " ); +fcall *fentry(one);}; + "[" => {print!( "{}", "[ " ); +fcall *fentry(two);}; + ']' sp* => {print!( "{}", "] " ); +fret;}; + [a-z]+ => {print!( "{}", "word " ); +val = 2; +fgoto *fentry(handle);}; + ' ' => {print!( "{}", "space " ); +}; + *|; + + main := |* + '{' => {print!( "{}", "{ " ); +fcall one;}; + "[" => {print!( "{}", "[ " ); +fcall two;}; + [a-z]+ => {print!( "{}", "word " ); +val = 3; +fgoto handle;}; + [a-z] ' foil' => {print!( "{}", "this is the foil" ); +}; + ' ' => {print!( "{}", "space " ); +}; + '\n'; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= GotoCallRet_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "{a{b[c d]d}c}\n".to_string() ); } + unsafe { m( "[a{b[c d]d}c}\n".to_string() ); } + unsafe { m( "[a[b]c]d{ef{g{h}i}j}l\n".to_string() ); } + unsafe { m( "{{[]}}\n".to_string() ); } + unsafe { m( "a b c\n".to_string() ); } + unsafe { m( "{a b c}\n".to_string() ); } + unsafe { m( "[a b c]\n".to_string() ); } + unsafe { m( "{]\n".to_string() ); } + unsafe { m( "{{}\n".to_string() ); } + unsafe { m( "[[[[[[]]]]]]\n".to_string() ); } + unsafe { m( "[[[[[[]]}]]]\n".to_string() ); } +} + diff --git a/test/trans.d/case/gotocallret3.rl b/test/trans.d/case/gotocallret3.rl new file mode 100644 index 00000000..d2c5e71a --- /dev/null +++ b/test/trans.d/case/gotocallret3.rl @@ -0,0 +1,121 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +/* + * Demonstrate the use of goto, call and return. This machine expects either a + * lower case char or a digit as a command then a space followed by the command + * arg. If the command is a char, then the arg must be an a string of chars. + * If the command is a digit, then the arg must be a string of digits. This + * choice is determined by action code, rather than though transition + * desitinations. + */ + +char comm; +int top; +int stack[32]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction { fentry(garble_line); } + + action err_garbling_line { print_str "error: garbling line\n"; } + action goto_main { fnext main; } + action recovery_failed { print_str "error: failed to recover\n"; } + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold; fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg { + if ( comm >= 97 ) { + fncall alp_comm; + } else { + fncall dig_comm; + } + } + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc;} ' ' @comm_arg @{print_str "prints\n";} '\n' + ) @{print_str "correct command\n";}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + +##### INPUT ##### +"lkajsdf\n" +"2134\n" +"(\n" +"\n" +"*234234()0909 092 -234aslkf09`1 11\n" +"1\n" +"909\n" +"1 a\n" +"11 1\n" +"a 1\n" +"aa a\n" +"1 1\n" +"1 123456\n" +"a a\n" +"a abcdef\n" +"h" +"a aa1" +##### OUTPUT ##### +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +error: garbling line +ACCEPT +prints +error: garbling line +ACCEPT +error: garbling line +ACCEPT +prints +error: garbling line +ACCEPT +error: garbling line +ACCEPT +prints +correct command +ACCEPT +prints +correct command +ACCEPT +prints +correct command +ACCEPT +prints +correct command +ACCEPT +FAIL +prints +error: garbling line +error: failed to recover +FAIL diff --git a/test/trans.d/case/gotocallret3_asm.rl b/test/trans.d/case/gotocallret3_asm.rl new file mode 100644 index 00000000..01a11cc0 --- /dev/null +++ b/test/trans.d/case/gotocallret3_asm.rl @@ -0,0 +1,292 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm comm,8,8 + .text + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction { + movq $fentry(garble_line), %rax + pushq %rax + popq %rax + +} + + action err_garbling_line { + .section .rodata +1: + .string "error: garbling line\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action goto_main { + fnext main; + +} + action recovery_failed { + .section .rodata +2: + .string "error: failed to recover\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return { + fhold; +fnret; + +} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg { + movq comm (%rip), %rax + pushq %rax + movq $97 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + setge %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 3f +fncall alp_comm; + + jmp 4f +3: +fncall dig_comm; + +4: + +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{ + movsbq (%r12), %rax + pushq %rax + popq %rax + movq %rax, comm (%rip) + +} ' ' @comm_arg @{ + .section .rodata +5: + .string "prints\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} '\n' + ) @{ + .section .rodata +6: + .string "correct command\n" + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{ + fhold; +fnext garble_line; + +}; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq gotocallret_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "lkajsdf\n" +.L_inp_1: + .string "2134\n" +.L_inp_2: + .string "(\n" +.L_inp_3: + .string "\n" +.L_inp_4: + .string "*234234()0909 092 -234aslkf09`1 11\n" +.L_inp_5: + .string "1\n" +.L_inp_6: + .string "909\n" +.L_inp_7: + .string "1 a\n" +.L_inp_8: + .string "11 1\n" +.L_inp_9: + .string "a 1\n" +.L_inp_10: + .string "aa a\n" +.L_inp_11: + .string "1 1\n" +.L_inp_12: + .string "1 123456\n" +.L_inp_13: + .string "a a\n" +.L_inp_14: + .string "a abcdef\n" +.L_inp_15: + .string "h" +.L_inp_16: + .string "a aa1" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + .quad .L_inp_7 + .quad .L_inp_8 + .quad .L_inp_9 + .quad .L_inp_10 + .quad .L_inp_11 + .quad .L_inp_12 + .quad .L_inp_13 + .quad .L_inp_14 + .quad .L_inp_15 + .quad .L_inp_16 + + .align 8 +inplen: + .quad 17 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/gotocallret3_c.rl b/test/trans.d/case/gotocallret3_c.rl new file mode 100644 index 00000000..13195f33 --- /dev/null +++ b/test/trans.d/case/gotocallret3_c.rl @@ -0,0 +1,123 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char comm ; +int top ; +int stack [32]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {printf( "%s", "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {printf( "%s", "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{printf( "%s", "prints\n" ); +} '\n' + ) @{printf( "%s", "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= gotocallret_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +int inplen = 17; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret3_crack.rl b/test/trans.d/case/gotocallret3_crack.rl new file mode 100644 index 00000000..73164ef8 --- /dev/null +++ b/test/trans.d/case/gotocallret3_crack.rl @@ -0,0 +1,108 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +byte comm; +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {cout.format( "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {cout.format( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{cout.format( "prints\n" ); +} '\n' + ) @{cout.format( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= gotocallret_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "lkajsdf\n" ); + m( "2134\n" ); + m( "(\n" ); + m( "\n" ); + m( "*234234()0909 092 -234aslkf09`1 11\n" ); + m( "1\n" ); + m( "909\n" ); + m( "1 a\n" ); + m( "11 1\n" ); + m( "a 1\n" ); + m( "aa a\n" ); + m( "1 1\n" ); + m( "1 123456\n" ); + m( "a a\n" ); + m( "a abcdef\n" ); + m( "h" ); + m( "a aa1" ); +} + +main(); diff --git a/test/trans.d/case/gotocallret3_cs.rl b/test/trans.d/case/gotocallret3_cs.rl new file mode 100644 index 00000000..4b5d34f1 --- /dev/null +++ b/test/trans.d/case/gotocallret3_cs.rl @@ -0,0 +1,123 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +char comm; +int top; +int [] stack = new int [32]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {Console.Write( "error: garbling line\n" );} + action goto_main {fnext main;} + action recovery_failed {Console.Write( "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{Console.Write( "prints\n" );} '\n' + ) @{Console.Write( "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= gotocallret_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + + +static readonly int inplen = 17; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/gotocallret3_d.rl b/test/trans.d/case/gotocallret3_d.rl new file mode 100644 index 00000000..eb95f265 --- /dev/null +++ b/test/trans.d/case/gotocallret3_d.rl @@ -0,0 +1,123 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class gotocallret +{ +char comm; +int top; +int stack[32]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {printf( "%.*s", "error: garbling line\n" );} + action goto_main {fnext main;} + action recovery_failed {printf( "%.*s", "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{printf( "%.*s", "prints\n" );} '\n' + ) @{printf( "%.*s", "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= gotocallret_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +]; + +int inplen = 17; + +} +int main() +{ + gotocallret m = new gotocallret(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/gotocallret3_go.rl b/test/trans.d/case/gotocallret3_go.rl new file mode 100644 index 00000000..5c27bfc1 --- /dev/null +++ b/test/trans.d/case/gotocallret3_go.rl @@ -0,0 +1,116 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var comm byte ; +var top int ; +var stack [32] int ; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {fmt.Print( "error: garbling line\n" );} + action goto_main {fnext main; +} + action recovery_failed {fmt.Print( "error: failed to recover\n" );} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold; +fnret; +} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) { + fncall alp_comm; + + +} else { + fncall dig_comm; + + +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{fmt.Print( "prints\n" );} '\n' + ) @{fmt.Print( "correct command\n" );}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold; +fnext garble_line; +}; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= gotocallret_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/gotocallret3_java.rl b/test/trans.d/case/gotocallret3_java.rl new file mode 100644 index 00000000..d27e33b8 --- /dev/null +++ b/test/trans.d/case/gotocallret3_java.rl @@ -0,0 +1,124 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class gotocallret3_java +{ +char comm ; +int top ; +int stack [] = new int[32]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {System.out.print( "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {System.out.print( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{System.out.print( "prints\n" ); +} '\n' + ) @{System.out.print( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= gotocallret_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +}; + +static final int inplen = 17; + +public static void main (String[] args) +{ + gotocallret3_java machine = new gotocallret3_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/gotocallret3_julia.rl b/test/trans.d/case/gotocallret3_julia.rl new file mode 100644 index 00000000..af78871b --- /dev/null +++ b/test/trans.d/case/gotocallret3_julia.rl @@ -0,0 +1,95 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {print( "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {print( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) + fncall alp_comm; +else + fncall dig_comm; +end +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{print( "prints\n" ); +} '\n' + ) @{print( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +comm = 0; +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + %% write init; + %% write exec; + + if ( cs >= gotocallret_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "lkajsdf\n" ); + m( "2134\n" ); + m( "(\n" ); + m( "\n" ); + m( "*234234()0909 092 -234aslkf09`1 11\n" ); + m( "1\n" ); + m( "909\n" ); + m( "1 a\n" ); + m( "11 1\n" ); + m( "a 1\n" ); + m( "aa a\n" ); + m( "1 1\n" ); + m( "1 123456\n" ); + m( "a a\n" ); + m( "a abcdef\n" ); + m( "h" ); + m( "a aa1" ); diff --git a/test/trans.d/case/gotocallret3_ocaml.rl b/test/trans.d/case/gotocallret3_ocaml.rl new file mode 100644 index 00000000..d4d243cc --- /dev/null +++ b/test/trans.d/case/gotocallret3_ocaml.rl @@ -0,0 +1,104 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let comm = ref 0 +let top = ref 0 +let stack = Array.make 32 0 + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry( garble_line ); +} + + action err_garbling_line {print_string( "error: garbling line\n" ); +} + action goto_main {fnext main; } + action recovery_failed {print_string( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold; fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if comm .contents >= 97 then +begin + fncall alp_comm; + +end +else +begin + fncall dig_comm; + +end +; +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm := fc; +} ' ' @comm_arg @{print_string( "prints\n" ); +} '\n' + ) @{print_string( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= gotocallret_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "lkajsdf\n"; + exec "2134\n"; + exec "(\n"; + exec "\n"; + exec "*234234()0909 092 -234aslkf09`1 11\n"; + exec "1\n"; + exec "909\n"; + exec "1 a\n"; + exec "11 1\n"; + exec "a 1\n"; + exec "aa a\n"; + exec "1 1\n"; + exec "1 123456\n"; + exec "a a\n"; + exec "a abcdef\n"; + exec "h"; + exec "a aa1"; + () +;; + diff --git a/test/trans.d/case/gotocallret3_ruby.rl b/test/trans.d/case/gotocallret3_ruby.rl new file mode 100644 index 00000000..78677d33 --- /dev/null +++ b/test/trans.d/case/gotocallret3_ruby.rl @@ -0,0 +1,103 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {print( "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {print( "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) + fncall alp_comm; +else + fncall dig_comm; +end +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{print( "prints\n" ); +} '\n' + ) @{print( "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +comm = 1 +top = 1 +stack = Array.new + %% write init; + %% write exec; + if cs >= gotocallret_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"lkajsdf\n", +"2134\n", +"(\n", +"\n", +"*234234()0909 092 -234aslkf09`1 11\n", +"1\n", +"909\n", +"1 a\n", +"11 1\n", +"a 1\n", +"aa a\n", +"1 1\n", +"1 123456\n", +"a a\n", +"a abcdef\n", +"h", +"a aa1", +] + +inplen = 17 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/gotocallret3_rust.rl b/test/trans.d/case/gotocallret3_rust.rl new file mode 100644 index 00000000..74982028 --- /dev/null +++ b/test/trans.d/case/gotocallret3_rust.rl @@ -0,0 +1,104 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut comm : u8 = 0; +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + +%%{ + machine gotocallret; + + # A reference to a state in an unused action caused a segfault in 5.8. */ + action unusedAction {fentry(garble_line); +} + + action err_garbling_line {print!( "{}", "error: garbling line\n" ); +} + action goto_main {fnext main;} + action recovery_failed {print!( "{}", "error: failed to recover\n" ); +} + + # Error machine, consumes to end of + # line, then starts the main line over. + garble_line := ( (any-'\n')*'\n') + >err_garbling_line + @goto_main + $/recovery_failed; + + action hold_and_return {fhold;fnret;} + + # Look for a string of alphas or of digits, + # on anything else, hold the character and return. + alp_comm := alpha+ $!hold_and_return; + dig_comm := digit+ $!hold_and_return; + + # Choose which to machine to call into based on the command. + action comm_arg {if ( comm >= 97 ) +{ + fncall alp_comm; +} +else { + fncall dig_comm; +} +} + + # Specifies command string. Note that the arg is left out. + command = ( + [a-z0-9] @{comm = fc; +} ' ' @comm_arg @{print!( "{}", "prints\n" ); +} '\n' + ) @{print!( "{}", "correct command\n" ); +}; + + # Any number of commands. If there is an + # error anywhere, garble the line. + main := command* $!{fhold;fnext garble_line;}; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= gotocallret_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "lkajsdf\n".to_string() ); } + unsafe { m( "2134\n".to_string() ); } + unsafe { m( "(\n".to_string() ); } + unsafe { m( "\n".to_string() ); } + unsafe { m( "*234234()0909 092 -234aslkf09`1 11\n".to_string() ); } + unsafe { m( "1\n".to_string() ); } + unsafe { m( "909\n".to_string() ); } + unsafe { m( "1 a\n".to_string() ); } + unsafe { m( "11 1\n".to_string() ); } + unsafe { m( "a 1\n".to_string() ); } + unsafe { m( "aa a\n".to_string() ); } + unsafe { m( "1 1\n".to_string() ); } + unsafe { m( "1 123456\n".to_string() ); } + unsafe { m( "a a\n".to_string() ); } + unsafe { m( "a abcdef\n".to_string() ); } + unsafe { m( "h".to_string() ); } + unsafe { m( "a aa1".to_string() ); } +} + diff --git a/test/trans.d/case/ncall1.rl b/test/trans.d/case/ncall1.rl new file mode 100644 index 00000000..9268ad31 --- /dev/null +++ b/test/trans.d/case/ncall1.rl @@ -0,0 +1,38 @@ +/* + * @LANG: indep + */ + +int top; +int stack[32]; + +int target; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + fnret; + }; + + two := 'two' @{ + print_str "two\n"; + fnret; + }; + + main := ( + '1' @{ target = fentry(one); fncall *target; } + | '2' @{ target = fentry(two); fncall *target; } + | '\n' + )*; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/ncall1_asm.rl b/test/trans.d/case/ncall1_asm.rl new file mode 100644 index 00000000..e8b97808 --- /dev/null +++ b/test/trans.d/case/ncall1_asm.rl @@ -0,0 +1,180 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + .section .data + .comm target,8,8 + .text + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fnret; + + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fnret; + + +}; + + main := ( + '1' @{ + movq $fentry(one), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fncall * %rcx; + +} + | '2' @{ + movq $fentry(two), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fncall * %rcx; + +} + | '\n' + )*; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq ncall1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/ncall1_c.rl b/test/trans.d/case/ncall1_c.rl new file mode 100644 index 00000000..142781da --- /dev/null +++ b/test/trans.d/case/ncall1_c.rl @@ -0,0 +1,76 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int top ; +int stack [32]; +int target ; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +fnret;}; + + two := 'two' @{printf( "%s", "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= ncall1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/ncall1_crack.rl b/test/trans.d/case/ncall1_crack.rl new file mode 100644 index 00000000..ee79a88a --- /dev/null +++ b/test/trans.d/case/ncall1_crack.rl @@ -0,0 +1,61 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +int target; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +fnret;}; + + two := 'two' @{cout.format( "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= ncall1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/ncall1_cs.rl b/test/trans.d/case/ncall1_cs.rl new file mode 100644 index 00000000..91abd9bb --- /dev/null +++ b/test/trans.d/case/ncall1_cs.rl @@ -0,0 +1,79 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int top; +int [] stack = new int [32]; +int target; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );fnret;}; + + two := 'two' @{Console.Write( "two\n" );fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= ncall1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/ncall1_d.rl b/test/trans.d/case/ncall1_d.rl new file mode 100644 index 00000000..29ec074a --- /dev/null +++ b/test/trans.d/case/ncall1_d.rl @@ -0,0 +1,78 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class ncall1 +{ +int top; +int stack[32]; +int target; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );fnret;}; + + two := 'two' @{printf( "%.*s", "two\n" );fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= ncall1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + ncall1 m = new ncall1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/ncall1_go.rl b/test/trans.d/case/ncall1_go.rl new file mode 100644 index 00000000..565b5d33 --- /dev/null +++ b/test/trans.d/case/ncall1_go.rl @@ -0,0 +1,70 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var top int ; +var stack [32] int ; +var target int ; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );fnret; + +}; + + two := 'two' @{fmt.Print( "two\n" );fnret; + +}; + + main := ( + '1' @{target = fentry(one); +fncall *target; +} + | '2' @{target = fentry(two); +fncall *target; +} + | '\n' + )*; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= ncall1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/ncall1_java.rl b/test/trans.d/case/ncall1_java.rl new file mode 100644 index 00000000..0576f26a --- /dev/null +++ b/test/trans.d/case/ncall1_java.rl @@ -0,0 +1,77 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class ncall1_java +{ +int top ; +int stack [] = new int[32]; +int target ; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +fnret;}; + + two := 'two' @{System.out.print( "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= ncall1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + ncall1_java machine = new ncall1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/ncall1_julia.rl b/test/trans.d/case/ncall1_julia.rl new file mode 100644 index 00000000..ec84a20b --- /dev/null +++ b/test/trans.d/case/ncall1_julia.rl @@ -0,0 +1,51 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnret;}; + + two := 'two' @{print( "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +target = 0; + + %% write init; + %% write exec; + + if ( cs >= ncall1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/ncall1_ocaml.rl b/test/trans.d/case/ncall1_ocaml.rl new file mode 100644 index 00000000..a1623c83 --- /dev/null +++ b/test/trans.d/case/ncall1_ocaml.rl @@ -0,0 +1,57 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let top = ref 0 +let stack = Array.make 32 0 +let target = ref 0 + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{print_string( "one\n" ); +fnret; + }; + + two := 'two' @{print_string( "two\n" ); +fnret; + }; + + main := ( + '1' @{target := fentry( one ); +fncall *target.contents; +} + | '2' @{target := fentry( two ); +fncall *target.contents; +} + | '\n' + )*; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= ncall1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1one2two1one\n"; + () +;; + diff --git a/test/trans.d/case/ncall1_ruby.rl b/test/trans.d/case/ncall1_ruby.rl new file mode 100644 index 00000000..b24f7f10 --- /dev/null +++ b/test/trans.d/case/ncall1_ruby.rl @@ -0,0 +1,59 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnret;}; + + two := 'two' @{print( "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +top = 1 +stack = Array.new +target = 1 + %% write init; + %% write exec; + if cs >= ncall1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1one2two1one\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/ncall1_rust.rl b/test/trans.d/case/ncall1_rust.rl new file mode 100644 index 00000000..77484cb4 --- /dev/null +++ b/test/trans.d/case/ncall1_rust.rl @@ -0,0 +1,58 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +static mut target : i32 = 0; + +%%{ + machine ncall1; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +fnret;}; + + two := 'two' @{print!( "{}", "two\n" ); +fnret;}; + + main := ( + '1' @{target = fentry(one); +fncall *target;} + | '2' @{target = fentry(two); +fncall *target;} + | '\n' + )*; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= ncall1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/next1.rl b/test/trans.d/case/next1.rl new file mode 100644 index 00000000..6b53f510 --- /dev/null +++ b/test/trans.d/case/next1.rl @@ -0,0 +1,36 @@ +/* + * @LANG: indep + */ + +int target; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + target = fentry(main); + fnext *target; + }; + + two := 'two' @{ + print_str "two\n"; + target = fentry(main); + fnext *target; + }; + + main := + '1' @{ target = fentry(one); fnext *target; } + | '2' @{ target = fentry(two); fnext *target; } + | '\n'; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/next1_asm.rl b/test/trans.d/case/next1_asm.rl new file mode 100644 index 00000000..3adf0962 --- /dev/null +++ b/test/trans.d/case/next1_asm.rl @@ -0,0 +1,187 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm target,8,8 + .text + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + main := + '1' @{ + movq $fentry(one), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +} + | '2' @{ + movq $fentry(two), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +} + | '\n'; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq next1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/next1_c.rl b/test/trans.d/case/next1_c.rl new file mode 100644 index 00000000..ddfcfa9c --- /dev/null +++ b/test/trans.d/case/next1_c.rl @@ -0,0 +1,75 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int target ; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{printf( "%s", "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/next1_crack.rl b/test/trans.d/case/next1_crack.rl new file mode 100644 index 00000000..e79755e9 --- /dev/null +++ b/test/trans.d/case/next1_crack.rl @@ -0,0 +1,60 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int target; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{cout.format( "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= next1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/next1_cs.rl b/test/trans.d/case/next1_cs.rl new file mode 100644 index 00000000..0d3719d0 --- /dev/null +++ b/test/trans.d/case/next1_cs.rl @@ -0,0 +1,78 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int target; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );target = fentry(main); +fnext *target;}; + + two := 'two' @{Console.Write( "two\n" );target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/next1_d.rl b/test/trans.d/case/next1_d.rl new file mode 100644 index 00000000..dda6b675 --- /dev/null +++ b/test/trans.d/case/next1_d.rl @@ -0,0 +1,77 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class next1 +{ +int target; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main); +fnext *target;}; + + two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= next1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + next1 m = new next1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/next1_go.rl b/test/trans.d/case/next1_go.rl new file mode 100644 index 00000000..030f8c20 --- /dev/null +++ b/test/trans.d/case/next1_go.rl @@ -0,0 +1,69 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var target int ; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );target = fentry(main); +fnext *target; + +}; + + two := 'two' @{fmt.Print( "two\n" );target = fentry(main); +fnext *target; + +}; + + main := + '1' @{target = fentry(one); +fnext *target; +} + | '2' @{target = fentry(two); +fnext *target; +} + | '\n'; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= next1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/next1_java.rl b/test/trans.d/case/next1_java.rl new file mode 100644 index 00000000..73c2c005 --- /dev/null +++ b/test/trans.d/case/next1_java.rl @@ -0,0 +1,76 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class next1_java +{ +int target ; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{System.out.print( "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + next1_java machine = new next1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/next1_julia.rl b/test/trans.d/case/next1_julia.rl new file mode 100644 index 00000000..6283255a --- /dev/null +++ b/test/trans.d/case/next1_julia.rl @@ -0,0 +1,50 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print( "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +target = 0; + + %% write init; + %% write exec; + + if ( cs >= next1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/next1_ocaml.rl b/test/trans.d/case/next1_ocaml.rl new file mode 100644 index 00000000..1e084a3f --- /dev/null +++ b/test/trans.d/case/next1_ocaml.rl @@ -0,0 +1,56 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let target = ref 0 + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{print_string( "one\n" ); +target := fentry( main ); +fnext *target.contents; +}; + + two := 'two' @{print_string( "two\n" ); +target := fentry( main ); +fnext *target.contents; +}; + + main := + '1' @{target := fentry( one ); +fnext *target.contents; +} + | '2' @{target := fentry( two ); +fnext *target.contents; +} + | '\n'; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= next1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1one2two1one\n"; + () +;; + diff --git a/test/trans.d/case/next1_ruby.rl b/test/trans.d/case/next1_ruby.rl new file mode 100644 index 00000000..d9611282 --- /dev/null +++ b/test/trans.d/case/next1_ruby.rl @@ -0,0 +1,58 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print( "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +target = 1 + %% write init; + %% write exec; + if cs >= next1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1one2two1one\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/next1_rust.rl b/test/trans.d/case/next1_rust.rl new file mode 100644 index 00000000..85470cae --- /dev/null +++ b/test/trans.d/case/next1_rust.rl @@ -0,0 +1,57 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut target : i32 = 0; + +%%{ + machine next1; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print!( "{}", "two\n" ); +target = fentry(main); +fnext *target;}; + + main := + '1' @{target = fentry(one); +fnext *target;} + | '2' @{target = fentry(two); +fnext *target;} + | '\n'; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= next1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/next2.rl b/test/trans.d/case/next2.rl new file mode 100644 index 00000000..9f8ffe2a --- /dev/null +++ b/test/trans.d/case/next2.rl @@ -0,0 +1,64 @@ +/* + * @LANG: indep + */ + +int target; +int last; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + target = fentry(main); + fnext *target; + }; + + two := 'two' @{ + print_str "two\n"; + target = fentry(main); + fnext *target; + }; + + three := 'three' @{ + print_str "three\n"; + target = fentry(main); + fnext *target; + }; + + main := ( + '1' @{ + target = fentry(one); + fnext *target; + last = 1; + } | + + '2' @{ + target = fentry(two); + fnext *target; + last = 2; + } | + + # This one is conditional based on the last. + '3' @{ + if ( last == 2 ) { + target = fentry(three); + fnext *target; + } + + last = 3; + } 'x' | + + '\n' + )*; +}%% + +##### INPUT ##### +"1one3x2two3three\n" +##### OUTPUT ##### +one +two +three +ACCEPT diff --git a/test/trans.d/case/next2_asm.rl b/test/trans.d/case/next2_asm.rl new file mode 100644 index 00000000..471f9fe1 --- /dev/null +++ b/test/trans.d/case/next2_asm.rl @@ -0,0 +1,256 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm target,8,8 + .text + .section .data + .comm last,8,8 + .text + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + three := 'three' @{ + .section .rodata +3: + .string "three\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq $fentry(main), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + main := ( + '1' @{ + movq $fentry(one), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + movq $1, %rax + pushq %rax + popq %rax + movq %rax, last (%rip) + +} | + + '2' @{ + movq $fentry(two), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + movq $2, %rax + pushq %rax + popq %rax + movq %rax, last (%rip) + +} | + + # This one is conditional based on the last. + '3' @{ + movq last (%rip), %rax + pushq %rax + movq $2 , %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 4f + movq $fentry(three), %rax + pushq %rax + popq %rax + movq %rax, target (%rip) + movq target(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; +4: + movq $3, %rax + pushq %rax + popq %rax + movq %rax, last (%rip) + +} 'x' | + + '\n' + )*; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq next2_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one3x2two3three\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/next2_c.rl b/test/trans.d/case/next2_c.rl new file mode 100644 index 00000000..1251e563 --- /dev/null +++ b/test/trans.d/case/next2_c.rl @@ -0,0 +1,94 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int target ; +int last ; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{printf( "%s", "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{printf( "%s", "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next2_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one3x2two3three\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/next2_crack.rl b/test/trans.d/case/next2_crack.rl new file mode 100644 index 00000000..9e90f50f --- /dev/null +++ b/test/trans.d/case/next2_crack.rl @@ -0,0 +1,79 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int target; +int last; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{cout.format( "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{cout.format( "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= next2_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one3x2two3three\n" ); +} + +main(); diff --git a/test/trans.d/case/next2_cs.rl b/test/trans.d/case/next2_cs.rl new file mode 100644 index 00000000..d0cd61d3 --- /dev/null +++ b/test/trans.d/case/next2_cs.rl @@ -0,0 +1,96 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int target; +int last; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );target = fentry(main); +fnext *target;}; + + two := 'two' @{Console.Write( "two\n" );target = fentry(main); +fnext *target;}; + + three := 'three' @{Console.Write( "three\n" );target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next2_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one3x2two3three\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/next2_d.rl b/test/trans.d/case/next2_d.rl new file mode 100644 index 00000000..146fff5d --- /dev/null +++ b/test/trans.d/case/next2_d.rl @@ -0,0 +1,95 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class next2 +{ +int target; +int last; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );target = fentry(main); +fnext *target;}; + + two := 'two' @{printf( "%.*s", "two\n" );target = fentry(main); +fnext *target;}; + + three := 'three' @{printf( "%.*s", "three\n" );target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= next2_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one3x2two3three\n", +]; + +int inplen = 1; + +} +int main() +{ + next2 m = new next2(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/next2_go.rl b/test/trans.d/case/next2_go.rl new file mode 100644 index 00000000..a019ebd4 --- /dev/null +++ b/test/trans.d/case/next2_go.rl @@ -0,0 +1,92 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var target int ; +var last int ; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );target = fentry(main); +fnext *target; + +}; + + two := 'two' @{fmt.Print( "two\n" );target = fentry(main); +fnext *target; + +}; + + three := 'three' @{fmt.Print( "three\n" );target = fentry(main); +fnext *target; + +}; + + main := ( + '1' @{target = fentry(one); +fnext *target; + +last = 1; +} | + + '2' @{target = fentry(two); +fnext *target; + +last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) { + target = fentry(three); +fnext *target; + + +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= next2_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one3x2two3three\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/next2_java.rl b/test/trans.d/case/next2_java.rl new file mode 100644 index 00000000..3fb7a4f7 --- /dev/null +++ b/test/trans.d/case/next2_java.rl @@ -0,0 +1,95 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class next2_java +{ +int target ; +int last ; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{System.out.print( "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{System.out.print( "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= next2_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one3x2two3three\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + next2_java machine = new next2_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/next2_julia.rl b/test/trans.d/case/next2_julia.rl new file mode 100644 index 00000000..43ae242c --- /dev/null +++ b/test/trans.d/case/next2_julia.rl @@ -0,0 +1,68 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print( "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{print( "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) + target = fentry(three); +fnext *target; +end +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +target = 0; +last = 0; + + %% write init; + %% write exec; + + if ( cs >= next2_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one3x2two3three\n" ); diff --git a/test/trans.d/case/next2_ocaml.rl b/test/trans.d/case/next2_ocaml.rl new file mode 100644 index 00000000..6357296d --- /dev/null +++ b/test/trans.d/case/next2_ocaml.rl @@ -0,0 +1,78 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let target = ref 0 +let last = ref 0 + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{print_string( "one\n" ); +target := fentry( main ); +fnext *target.contents; +}; + + two := 'two' @{print_string( "two\n" ); +target := fentry( main ); +fnext *target.contents; +}; + + three := 'three' @{print_string( "three\n" ); +target := fentry( main ); +fnext *target.contents; +}; + + main := ( + '1' @{target := fentry( one ); +fnext *target.contents; +last := 1; +} | + + '2' @{target := fentry( two ); +fnext *target.contents; +last := 2; +} | + + # This one is conditional based on the last. + '3' @{if last .contents == 2 then +begin + target := fentry( three ); +fnext *target.contents; + +end +; +last := 3; +} 'x' | + + '\n' + )*; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= next2_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1one3x2two3three\n"; + () +;; + diff --git a/test/trans.d/case/next2_ruby.rl b/test/trans.d/case/next2_ruby.rl new file mode 100644 index 00000000..94b8ce98 --- /dev/null +++ b/test/trans.d/case/next2_ruby.rl @@ -0,0 +1,76 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print( "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{print( "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) + target = fentry(three); +fnext *target; +end +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +target = 1 +last = 1 + %% write init; + %% write exec; + if cs >= next2_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1one3x2two3three\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/next2_rust.rl b/test/trans.d/case/next2_rust.rl new file mode 100644 index 00000000..d712cf26 --- /dev/null +++ b/test/trans.d/case/next2_rust.rl @@ -0,0 +1,76 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut target : i32 = 0; +static mut last : i32 = 0; + +%%{ + machine next2; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +target = fentry(main); +fnext *target;}; + + two := 'two' @{print!( "{}", "two\n" ); +target = fentry(main); +fnext *target;}; + + three := 'three' @{print!( "{}", "three\n" ); +target = fentry(main); +fnext *target;}; + + main := ( + '1' @{target = fentry(one); +fnext *target;last = 1; +} | + + '2' @{target = fentry(two); +fnext *target;last = 2; +} | + + # This one is conditional based on the last. + '3' @{if ( last == 2 ) +{ + target = fentry(three); +fnext *target; +} +last = 3; +} 'x' | + + '\n' + )*; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= next2_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one3x2two3three\n".to_string() ); } +} + diff --git a/test/trans.d/case/patact.rl b/test/trans.d/case/patact.rl new file mode 100644 index 00000000..1e16c63a --- /dev/null +++ b/test/trans.d/case/patact.rl @@ -0,0 +1,99 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +char comm; +int top; +int stack[32]; +ptr ts; +ptr te; +int act; +int value; + +%%{ + machine patact; + + other := |* + [a-z]+ => { print_str "word\n"; }; + [0-9]+ => { print_str "num\n"; }; + [\n ] => { print_str "space\n"; }; + *|; + + exec_test := |* + [a-z]+ => { print_str "word (w/lbh)\n"; fexec te-1; fgoto other; }; + [a-z]+ ' foil' => { print_str "word (c/lbh)\n"; }; + [\n ] => { print_str "space\n"; }; + '22' => { print_str "num (w/switch)\n"; }; + [0-9]+ => { print_str "num (w/switch)\n"; fexec te-1; fgoto other;}; + [0-9]+ ' foil' => {print_str "num (c/switch)\n"; }; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => { print_str "in semi\n"; fgoto main; }; + *|; + + main := |* + [a-z]+ => { print_str "word (w/lbh)\n"; fhold; fgoto other; }; + [a-z]+ ' foil' => { print_str "word (c/lbh)\n"; }; + [\n ] => { print_str "space\n"; }; + '22' => { print_str "num (w/switch)\n"; }; + [0-9]+ => { print_str "num (w/switch)\n"; fhold; fgoto other;}; + [0-9]+ ' foil' => {print_str "num (c/switch)\n"; }; + ';' => { print_str "going to semi\n"; fhold; fgoto semi;}; + '!' => { print_str "immdiate\n"; fgoto exec_test; }; + *|; +}%% + +##### INPUT ##### +"abcd foix\n" +"abcd\nanother\n" +"123 foix\n" +"!abcd foix\n" +"!abcd\nanother\n" +"!123 foix\n" +";" +##### OUTPUT ##### +word (w/lbh) +word +space +word +space +ACCEPT +word (w/lbh) +word +space +word +space +ACCEPT +num (w/switch) +num +space +word +space +ACCEPT +immdiate +word (w/lbh) +word +space +word +space +ACCEPT +immdiate +word (w/lbh) +word +space +word +space +ACCEPT +immdiate +num (w/switch) +num +space +word +space +ACCEPT +going to semi +in semi +ACCEPT diff --git a/test/trans.d/case/patact_asm.rl b/test/trans.d/case/patact_asm.rl new file mode 100644 index 00000000..246cca71 --- /dev/null +++ b/test/trans.d/case/patact_asm.rl @@ -0,0 +1,426 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm comm,8,8 + .text + .section .data + .comm top,8,8 + .text + .section .data + .comm stack,8,8 + .text + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm value,8,8 + .text + +%%{ + machine patact; + + other := |* + [a-z]+ => { + .section .rodata +1: + .string "word\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [0-9]+ => { + .section .rodata +2: + .string "num\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [\n ] => { + .section .rodata +3: + .string "space\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; + + exec_test := |* + [a-z]+ => { + .section .rodata +4: + .string "word (w/lbh)\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -24(%rbp), %rax + pushq %rax + movq $1, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rax + fexec %rax; +fgoto other; + +}; + [a-z]+ ' foil' => { + .section .rodata +5: + .string "word (c/lbh)\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [\n ] => { + .section .rodata +6: + .string "space\n" + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '22' => { + .section .rodata +7: + .string "num (w/switch)\n" + .text + movq $7b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [0-9]+ => { + .section .rodata +8: + .string "num (w/switch)\n" + .text + movq $8b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq -24(%rbp), %rax + pushq %rax + movq $1, %rax + pushq %rax + popq %rcx + popq %rax + subq %rcx, %rax + pushq %rax + popq %rax + fexec %rax; +fgoto other; + +}; + [0-9]+ ' foil' => { + .section .rodata +9: + .string "num (c/switch)\n" + .text + movq $9b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => { + .section .rodata +10: + .string "in semi\n" + .text + movq $10b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fgoto main; + +}; + *|; + + main := |* + [a-z]+ => { + .section .rodata +11: + .string "word (w/lbh)\n" + .text + movq $11b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fhold; +fgoto other; + +}; + [a-z]+ ' foil' => { + .section .rodata +12: + .string "word (c/lbh)\n" + .text + movq $12b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [\n ] => { + .section .rodata +13: + .string "space\n" + .text + movq $13b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + '22' => { + .section .rodata +14: + .string "num (w/switch)\n" + .text + movq $14b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [0-9]+ => { + .section .rodata +15: + .string "num (w/switch)\n" + .text + movq $15b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fhold; +fgoto other; + +}; + [0-9]+ ' foil' => { + .section .rodata +16: + .string "num (c/switch)\n" + .text + movq $16b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + ';' => { + .section .rodata +17: + .string "going to semi\n" + .text + movq $17b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fhold; +fgoto semi; + +}; + '!' => { + .section .rodata +18: + .string "immdiate\n" + .text + movq $18b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +fgoto exec_test; + +}; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq patact_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "abcd foix\n" +.L_inp_1: + .string "abcd\nanother\n" +.L_inp_2: + .string "123 foix\n" +.L_inp_3: + .string "!abcd foix\n" +.L_inp_4: + .string "!abcd\nanother\n" +.L_inp_5: + .string "!123 foix\n" +.L_inp_6: + .string ";" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + .quad .L_inp_5 + .quad .L_inp_6 + + .align 8 +inplen: + .quad 7 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/patact_c.rl b/test/trans.d/case/patact_c.rl new file mode 100644 index 00000000..e3a7df35 --- /dev/null +++ b/test/trans.d/case/patact_c.rl @@ -0,0 +1,120 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char comm ; +int top ; +int stack [32]; +char * ts ; +char * te ; +int act ; +int value ; + +%%{ + machine patact; + + other := |* + [a-z]+ => {printf( "%s", "word\n" ); +}; + [0-9]+ => {printf( "%s", "num\n" ); +}; + [\n ] => {printf( "%s", "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {printf( "%s", "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {printf( "%s", "word (c/lbh)\n" ); +}; + [\n ] => {printf( "%s", "space\n" ); +}; + '22' => {printf( "%s", "num (w/switch)\n" ); +}; + [0-9]+ => {printf( "%s", "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {printf( "%s", "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {printf( "%s", "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {printf( "%s", "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {printf( "%s", "word (c/lbh)\n" ); +}; + [\n ] => {printf( "%s", "space\n" ); +}; + '22' => {printf( "%s", "num (w/switch)\n" ); +}; + [0-9]+ => {printf( "%s", "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {printf( "%s", "num (c/switch)\n" ); +}; + ';' => {printf( "%s", "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {printf( "%s", "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= patact_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +}; + +int inplen = 7; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/patact_crack.rl b/test/trans.d/case/patact_crack.rl new file mode 100644 index 00000000..f4da2926 --- /dev/null +++ b/test/trans.d/case/patact_crack.rl @@ -0,0 +1,107 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +byte comm; +int top; +array[int] stack = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +int + ts; +int + te; +int act; +int value; + +%%{ + machine patact; + + other := |* + [a-z]+ => {cout.format( "word\n" ); +}; + [0-9]+ => {cout.format( "num\n" ); +}; + [\n ] => {cout.format( "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {cout.format( "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {cout.format( "word (c/lbh)\n" ); +}; + [\n ] => {cout.format( "space\n" ); +}; + '22' => {cout.format( "num (w/switch)\n" ); +}; + [0-9]+ => {cout.format( "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {cout.format( "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {cout.format( "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {cout.format( "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {cout.format( "word (c/lbh)\n" ); +}; + [\n ] => {cout.format( "space\n" ); +}; + '22' => {cout.format( "num (w/switch)\n" ); +}; + [0-9]+ => {cout.format( "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {cout.format( "num (c/switch)\n" ); +}; + ';' => {cout.format( "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {cout.format( "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= patact_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "abcd foix\n" ); + m( "abcd\nanother\n" ); + m( "123 foix\n" ); + m( "!abcd foix\n" ); + m( "!abcd\nanother\n" ); + m( "!123 foix\n" ); + m( ";" ); +} + +main(); diff --git a/test/trans.d/case/patact_cs.rl b/test/trans.d/case/patact_cs.rl new file mode 100644 index 00000000..da82bac9 --- /dev/null +++ b/test/trans.d/case/patact_cs.rl @@ -0,0 +1,106 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +char comm; +int top; +int [] stack = new int [32]; +int ts; +int te; +int act; +int value; + +%%{ + machine patact; + + other := |* + [a-z]+ => {Console.Write( "word\n" );}; + [0-9]+ => {Console.Write( "num\n" );}; + [\n ] => {Console.Write( "space\n" );}; + *|; + + exec_test := |* + [a-z]+ => {Console.Write( "word (w/lbh)\n" );fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {Console.Write( "word (c/lbh)\n" );}; + [\n ] => {Console.Write( "space\n" );}; + '22' => {Console.Write( "num (w/switch)\n" );}; + [0-9]+ => {Console.Write( "num (w/switch)\n" );fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {Console.Write( "num (c/switch)\n" );}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {Console.Write( "in semi\n" );fgoto main;}; + *|; + + main := |* + [a-z]+ => {Console.Write( "word (w/lbh)\n" );fhold;fgoto other;}; + [a-z]+ ' foil' => {Console.Write( "word (c/lbh)\n" );}; + [\n ] => {Console.Write( "space\n" );}; + '22' => {Console.Write( "num (w/switch)\n" );}; + [0-9]+ => {Console.Write( "num (w/switch)\n" );fhold;fgoto other;}; + [0-9]+ ' foil' => {Console.Write( "num (c/switch)\n" );}; + ';' => {Console.Write( "going to semi\n" );fhold;fgoto semi;}; + '!' => {Console.Write( "immdiate\n" );fgoto exec_test;}; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= patact_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +}; + + +static readonly int inplen = 7; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/patact_d.rl b/test/trans.d/case/patact_d.rl new file mode 100644 index 00000000..94b65eb2 --- /dev/null +++ b/test/trans.d/case/patact_d.rl @@ -0,0 +1,106 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class patact +{ +char comm; +int top; +int stack[32]; +const(char) * ts; +const(char) * te; +int act; +int value; + +%%{ + machine patact; + + other := |* + [a-z]+ => {printf( "%.*s", "word\n" );}; + [0-9]+ => {printf( "%.*s", "num\n" );}; + [\n ] => {printf( "%.*s", "space\n" );}; + *|; + + exec_test := |* + [a-z]+ => {printf( "%.*s", "word (w/lbh)\n" );fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {printf( "%.*s", "word (c/lbh)\n" );}; + [\n ] => {printf( "%.*s", "space\n" );}; + '22' => {printf( "%.*s", "num (w/switch)\n" );}; + [0-9]+ => {printf( "%.*s", "num (w/switch)\n" );fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {printf( "%.*s", "num (c/switch)\n" );}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {printf( "%.*s", "in semi\n" );fgoto main;}; + *|; + + main := |* + [a-z]+ => {printf( "%.*s", "word (w/lbh)\n" );fhold;fgoto other;}; + [a-z]+ ' foil' => {printf( "%.*s", "word (c/lbh)\n" );}; + [\n ] => {printf( "%.*s", "space\n" );}; + '22' => {printf( "%.*s", "num (w/switch)\n" );}; + [0-9]+ => {printf( "%.*s", "num (w/switch)\n" );fhold;fgoto other;}; + [0-9]+ ' foil' => {printf( "%.*s", "num (c/switch)\n" );}; + ';' => {printf( "%.*s", "going to semi\n" );fhold;fgoto semi;}; + '!' => {printf( "%.*s", "immdiate\n" );fgoto exec_test;}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= patact_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +]; + +int inplen = 7; + +} +int main() +{ + patact m = new patact(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/patact_go.rl b/test/trans.d/case/patact_go.rl new file mode 100644 index 00000000..2ee97c36 --- /dev/null +++ b/test/trans.d/case/patact_go.rl @@ -0,0 +1,104 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var comm byte ; +var top int ; +var stack [32] int ; +var ts int ; +var te int ; +var act int ; +var value int ; + +%%{ + machine patact; + + other := |* + [a-z]+ => {fmt.Print( "word\n" );}; + [0-9]+ => {fmt.Print( "num\n" );}; + [\n ] => {fmt.Print( "space\n" );}; + *|; + + exec_test := |* + [a-z]+ => {fmt.Print( "word (w/lbh)\n" );fexec te-1; +fgoto other; +}; + [a-z]+ ' foil' => {fmt.Print( "word (c/lbh)\n" );}; + [\n ] => {fmt.Print( "space\n" );}; + '22' => {fmt.Print( "num (w/switch)\n" );}; + [0-9]+ => {fmt.Print( "num (w/switch)\n" );fexec te-1; +fgoto other; +}; + [0-9]+ ' foil' => {fmt.Print( "num (c/switch)\n" );}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {fmt.Print( "in semi\n" );fgoto main; +}; + *|; + + main := |* + [a-z]+ => {fmt.Print( "word (w/lbh)\n" );fhold; +fgoto other; +}; + [a-z]+ ' foil' => {fmt.Print( "word (c/lbh)\n" );}; + [\n ] => {fmt.Print( "space\n" );}; + '22' => {fmt.Print( "num (w/switch)\n" );}; + [0-9]+ => {fmt.Print( "num (w/switch)\n" );fhold; +fgoto other; +}; + [0-9]+ ' foil' => {fmt.Print( "num (c/switch)\n" );}; + ';' => {fmt.Print( "going to semi\n" );fhold; +fgoto semi; +}; + '!' => {fmt.Print( "immdiate\n" );fgoto exec_test; +}; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= patact_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/patact_java.rl b/test/trans.d/case/patact_java.rl new file mode 100644 index 00000000..7ff06d11 --- /dev/null +++ b/test/trans.d/case/patact_java.rl @@ -0,0 +1,123 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class patact_java +{ +char comm ; +int top ; +int stack [] = new int[32]; +int + ts ; +int + te ; +int act ; +int value ; + +%%{ + machine patact; + + other := |* + [a-z]+ => {System.out.print( "word\n" ); +}; + [0-9]+ => {System.out.print( "num\n" ); +}; + [\n ] => {System.out.print( "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {System.out.print( "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {System.out.print( "word (c/lbh)\n" ); +}; + [\n ] => {System.out.print( "space\n" ); +}; + '22' => {System.out.print( "num (w/switch)\n" ); +}; + [0-9]+ => {System.out.print( "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {System.out.print( "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {System.out.print( "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {System.out.print( "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {System.out.print( "word (c/lbh)\n" ); +}; + [\n ] => {System.out.print( "space\n" ); +}; + '22' => {System.out.print( "num (w/switch)\n" ); +}; + [0-9]+ => {System.out.print( "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {System.out.print( "num (c/switch)\n" ); +}; + ';' => {System.out.print( "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {System.out.print( "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= patact_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +}; + +static final int inplen = 7; + +public static void main (String[] args) +{ + patact_java machine = new patact_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/patact_julia.rl b/test/trans.d/case/patact_julia.rl new file mode 100644 index 00000000..a6f69ee9 --- /dev/null +++ b/test/trans.d/case/patact_julia.rl @@ -0,0 +1,94 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine patact; + + other := |* + [a-z]+ => {print( "word\n" ); +}; + [0-9]+ => {print( "num\n" ); +}; + [\n ] => {print( "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {print( "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {print( "word (c/lbh)\n" ); +}; + [\n ] => {print( "space\n" ); +}; + '22' => {print( "num (w/switch)\n" ); +}; + [0-9]+ => {print( "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {print( "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {print( "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {print( "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {print( "word (c/lbh)\n" ); +}; + [\n ] => {print( "space\n" ); +}; + '22' => {print( "num (w/switch)\n" ); +}; + [0-9]+ => {print( "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {print( "num (c/switch)\n" ); +}; + ';' => {print( "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {print( "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +comm = 0; +top = 0; +stack = Int [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +ts = 0; +te = 0; +act = 0; +value = 0; + + %% write init; + %% write exec; + + if ( cs >= patact_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "abcd foix\n" ); + m( "abcd\nanother\n" ); + m( "123 foix\n" ); + m( "!abcd foix\n" ); + m( "!abcd\nanother\n" ); + m( "!123 foix\n" ); + m( ";" ); diff --git a/test/trans.d/case/patact_ocaml.rl b/test/trans.d/case/patact_ocaml.rl new file mode 100644 index 00000000..1775c8ce --- /dev/null +++ b/test/trans.d/case/patact_ocaml.rl @@ -0,0 +1,97 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let comm = ref 0 +let top = ref 0 +let stack = Array.make 32 0 +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let value = ref 0 + +%%{ + machine patact; + + other := |* + [a-z]+ => {print_string( "word\n" ); +}; + [0-9]+ => {print_string( "num\n" ); +}; + [\n ] => {print_string( "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {print_string( "word (w/lbh)\n" ); +fexec te-1; fgoto other; }; + [a-z]+ ' foil' => {print_string( "word (c/lbh)\n" ); +}; + [\n ] => {print_string( "space\n" ); +}; + '22' => {print_string( "num (w/switch)\n" ); +}; + [0-9]+ => {print_string( "num (w/switch)\n" ); +fexec te-1; fgoto other;}; + [0-9]+ ' foil' => {print_string( "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {print_string( "in semi\n" ); +fgoto main; }; + *|; + + main := |* + [a-z]+ => {print_string( "word (w/lbh)\n" ); +fhold; fgoto other; }; + [a-z]+ ' foil' => {print_string( "word (c/lbh)\n" ); +}; + [\n ] => {print_string( "space\n" ); +}; + '22' => {print_string( "num (w/switch)\n" ); +}; + [0-9]+ => {print_string( "num (w/switch)\n" ); +fhold; fgoto other;}; + [0-9]+ ' foil' => {print_string( "num (c/switch)\n" ); +}; + ';' => {print_string( "going to semi\n" ); +fhold; fgoto semi;}; + '!' => {print_string( "immdiate\n" ); +fgoto exec_test; }; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= patact_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "abcd foix\n"; + exec "abcd\nanother\n"; + exec "123 foix\n"; + exec "!abcd foix\n"; + exec "!abcd\nanother\n"; + exec "!123 foix\n"; + exec ";"; + () +;; + diff --git a/test/trans.d/case/patact_ruby.rl b/test/trans.d/case/patact_ruby.rl new file mode 100644 index 00000000..43a535e6 --- /dev/null +++ b/test/trans.d/case/patact_ruby.rl @@ -0,0 +1,102 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine patact; + + other := |* + [a-z]+ => {print( "word\n" ); +}; + [0-9]+ => {print( "num\n" ); +}; + [\n ] => {print( "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {print( "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {print( "word (c/lbh)\n" ); +}; + [\n ] => {print( "space\n" ); +}; + '22' => {print( "num (w/switch)\n" ); +}; + [0-9]+ => {print( "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {print( "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {print( "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {print( "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {print( "word (c/lbh)\n" ); +}; + [\n ] => {print( "space\n" ); +}; + '22' => {print( "num (w/switch)\n" ); +}; + [0-9]+ => {print( "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {print( "num (c/switch)\n" ); +}; + ';' => {print( "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {print( "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +comm = 1 +top = 1 +stack = Array.new +ts = 1 +te = 1 +act = 1 +value = 1 + %% write init; + %% write exec; + if cs >= patact_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"abcd foix\n", +"abcd\nanother\n", +"123 foix\n", +"!abcd foix\n", +"!abcd\nanother\n", +"!123 foix\n", +";", +] + +inplen = 7 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/patact_rust.rl b/test/trans.d/case/patact_rust.rl new file mode 100644 index 00000000..8f660e1f --- /dev/null +++ b/test/trans.d/case/patact_rust.rl @@ -0,0 +1,103 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut comm : u8 = 0; +static mut top : i32 = 0; +static mut stack : [ i32 ; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut value : i32 = 0; + +%%{ + machine patact; + + other := |* + [a-z]+ => {print!( "{}", "word\n" ); +}; + [0-9]+ => {print!( "{}", "num\n" ); +}; + [\n ] => {print!( "{}", "space\n" ); +}; + *|; + + exec_test := |* + [a-z]+ => {print!( "{}", "word (w/lbh)\n" ); +fexec te-1;fgoto other;}; + [a-z]+ ' foil' => {print!( "{}", "word (c/lbh)\n" ); +}; + [\n ] => {print!( "{}", "space\n" ); +}; + '22' => {print!( "{}", "num (w/switch)\n" ); +}; + [0-9]+ => {print!( "{}", "num (w/switch)\n" ); +fexec te-1;fgoto other;}; + [0-9]+ ' foil' => {print!( "{}", "num (c/switch)\n" ); +}; + '!';# => { print_str "immdiate\n"; fgoto exec_test; }; + *|; + + semi := |* + ';' => {print!( "{}", "in semi\n" ); +fgoto main;}; + *|; + + main := |* + [a-z]+ => {print!( "{}", "word (w/lbh)\n" ); +fhold;fgoto other;}; + [a-z]+ ' foil' => {print!( "{}", "word (c/lbh)\n" ); +}; + [\n ] => {print!( "{}", "space\n" ); +}; + '22' => {print!( "{}", "num (w/switch)\n" ); +}; + [0-9]+ => {print!( "{}", "num (w/switch)\n" ); +fhold;fgoto other;}; + [0-9]+ ' foil' => {print!( "{}", "num (c/switch)\n" ); +}; + ';' => {print!( "{}", "going to semi\n" ); +fhold;fgoto semi;}; + '!' => {print!( "{}", "immdiate\n" ); +fgoto exec_test;}; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= patact_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "abcd foix\n".to_string() ); } + unsafe { m( "abcd\nanother\n".to_string() ); } + unsafe { m( "123 foix\n".to_string() ); } + unsafe { m( "!abcd foix\n".to_string() ); } + unsafe { m( "!abcd\nanother\n".to_string() ); } + unsafe { m( "!123 foix\n".to_string() ); } + unsafe { m( ";".to_string() ); } +} + diff --git a/test/trans.d/case/rangei.rl b/test/trans.d/case/rangei.rl new file mode 100644 index 00000000..1b523556 --- /dev/null +++ b/test/trans.d/case/rangei.rl @@ -0,0 +1,28 @@ +/* + * @LANG: indep + */ +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + +##### INPUT ##### +"AaBbAa" +"Aa`bAa" +"AaB@Aa" +"AaBbMa" +"AaBbma" +##### OUTPUT ##### +ACCEPT +FAIL +FAIL +FAIL +FAIL diff --git a/test/trans.d/case/rangei_asm.rl b/test/trans.d/case/rangei_asm.rl new file mode 100644 index 00000000..6906eb3b --- /dev/null +++ b/test/trans.d/case/rangei_asm.rl @@ -0,0 +1,131 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq rangei_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "AaBbAa" +.L_inp_1: + .string "Aa`bAa" +.L_inp_2: + .string "AaB@Aa" +.L_inp_3: + .string "AaBbMa" +.L_inp_4: + .string "AaBbma" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + .quad .L_inp_2 + .quad .L_inp_3 + .quad .L_inp_4 + + .align 8 +inplen: + .quad 5 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/rangei_c.rl b/test/trans.d/case/rangei_c.rl new file mode 100644 index 00000000..da69b0c2 --- /dev/null +++ b/test/trans.d/case/rangei_c.rl @@ -0,0 +1,71 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= rangei_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +}; + +int inplen = 5; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/rangei_crack.rl b/test/trans.d/case/rangei_crack.rl new file mode 100644 index 00000000..7816b6cd --- /dev/null +++ b/test/trans.d/case/rangei_crack.rl @@ -0,0 +1,56 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= rangei_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "AaBbAa" ); + m( "Aa`bAa" ); + m( "AaB@Aa" ); + m( "AaBbMa" ); + m( "AaBbma" ); +} + +main(); diff --git a/test/trans.d/case/rangei_cs.rl b/test/trans.d/case/rangei_cs.rl new file mode 100644 index 00000000..8b0dbe7e --- /dev/null +++ b/test/trans.d/case/rangei_cs.rl @@ -0,0 +1,76 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= rangei_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +}; + + +static readonly int inplen = 5; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/rangei_d.rl b/test/trans.d/case/rangei_d.rl new file mode 100644 index 00000000..fde4987c --- /dev/null +++ b/test/trans.d/case/rangei_d.rl @@ -0,0 +1,75 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class rangei +{ + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= rangei_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +]; + +int inplen = 5; + +} +int main() +{ + rangei m = new rangei(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/rangei_go.rl b/test/trans.d/case/rangei_go.rl new file mode 100644 index 00000000..2f17a6f2 --- /dev/null +++ b/test/trans.d/case/rangei_go.rl @@ -0,0 +1,61 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= rangei_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/rangei_java.rl b/test/trans.d/case/rangei_java.rl new file mode 100644 index 00000000..e437f259 --- /dev/null +++ b/test/trans.d/case/rangei_java.rl @@ -0,0 +1,72 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class rangei_java +{ + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= rangei_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +}; + +static final int inplen = 5; + +public static void main (String[] args) +{ + rangei_java machine = new rangei_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/rangei_julia.rl b/test/trans.d/case/rangei_julia.rl new file mode 100644 index 00000000..392950b3 --- /dev/null +++ b/test/trans.d/case/rangei_julia.rl @@ -0,0 +1,46 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= rangei_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "AaBbAa" ); + m( "Aa`bAa" ); + m( "AaB@Aa" ); + m( "AaBbMa" ); + m( "AaBbma" ); diff --git a/test/trans.d/case/rangei_ocaml.rl b/test/trans.d/case/rangei_ocaml.rl new file mode 100644 index 00000000..dbca2463 --- /dev/null +++ b/test/trans.d/case/rangei_ocaml.rl @@ -0,0 +1,48 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= rangei_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "AaBbAa"; + exec "Aa`bAa"; + exec "AaB@Aa"; + exec "AaBbMa"; + exec "AaBbma"; + () +;; + diff --git a/test/trans.d/case/rangei_ruby.rl b/test/trans.d/case/rangei_ruby.rl new file mode 100644 index 00000000..19db2bd9 --- /dev/null +++ b/test/trans.d/case/rangei_ruby.rl @@ -0,0 +1,54 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= rangei_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"AaBbAa", +"Aa`bAa", +"AaB@Aa", +"AaBbMa", +"AaBbma", +] + +inplen = 5 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/rangei_rust.rl b/test/trans.d/case/rangei_rust.rl new file mode 100644 index 00000000..40ea2815 --- /dev/null +++ b/test/trans.d/case/rangei_rust.rl @@ -0,0 +1,53 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + +%%{ + machine rangei; + + main := + 'a' ../i 'z' . + 'A' ../i 'Z' . + 60 ../i 93 . + 94 ../i 125 . + 86 ../i 101 . + 60 ../i 125 + ''; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= rangei_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "AaBbAa".to_string() ); } + unsafe { m( "Aa`bAa".to_string() ); } + unsafe { m( "AaB@Aa".to_string() ); } + unsafe { m( "AaBbMa".to_string() ); } + unsafe { m( "AaBbma".to_string() ); } +} + diff --git a/test/trans.d/case/scan1.rl b/test/trans.d/case/scan1.rl new file mode 100644 index 00000000..2675b601 --- /dev/null +++ b/test/trans.d/case/scan1.rl @@ -0,0 +1,70 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +ptr ts; +ptr te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + print_str "on last "; + if ( p+1 == te ) { + print_str "yes"; + } + print_str "\n"; + }; + + 'b'+ => { + print_str "on next "; + if ( p+1 == te ) { + print_str "yes"; + } + print_str "\n"; + }; + + 'c1' 'dxxx'? => { + print_str "on lag "; + if ( p+1 == te ) { + print_str "yes"; + } + print_str "\n"; + }; + + 'd1' => { + print_str "lm switch1 "; + if ( p+1 == te ) { + print_str "yes"; + } + print_str "\n"; + }; + 'd2' => { + print_str "lm switch2 "; + if ( p+1 == te ) { + print_str "yes"; + } + print_str "\n"; + }; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + +##### INPUT ##### +"abbc1d1d2\n" +##### OUTPUT ##### +on last yes +on next yes +on lag yes +lm switch1 yes +lm switch2 yes +ACCEPT diff --git a/test/trans.d/case/scan1_asm.rl b/test/trans.d/case/scan1_asm.rl new file mode 100644 index 00000000..999b0c4a --- /dev/null +++ b/test/trans.d/case/scan1_asm.rl @@ -0,0 +1,394 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm token,8,8 + .text + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + .section .rodata +1: + .string "on last " + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + pushq %r12 + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + movq -24(%rbp), %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 2f + .section .rodata +4: + .string "yes" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +2: + .section .rodata +5: + .string "\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + 'b'+ => { + .section .rodata +6: + .string "on next " + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + pushq %r12 + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + movq -24(%rbp), %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 7f + .section .rodata +9: + .string "yes" + .text + movq $9b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +7: + .section .rodata +10: + .string "\n" + .text + movq $10b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + 'c1' 'dxxx'? => { + .section .rodata +11: + .string "on lag " + .text + movq $11b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + pushq %r12 + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + movq -24(%rbp), %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 12f + .section .rodata +14: + .string "yes" + .text + movq $14b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +12: + .section .rodata +15: + .string "\n" + .text + movq $15b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + 'd1' => { + .section .rodata +16: + .string "lm switch1 " + .text + movq $16b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + pushq %r12 + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + movq -24(%rbp), %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 17f + .section .rodata +19: + .string "yes" + .text + movq $19b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +17: + .section .rodata +20: + .string "\n" + .text + movq $20b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + 'd2' => { + .section .rodata +21: + .string "lm switch2 " + .text + movq $21b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + pushq %r12 + movq $1 , %rax + pushq %rax + popq %rcx + popq %rax + addq %rcx, %rax + pushq %rax + movq -24(%rbp), %rax + pushq %rax + popq %rcx + popq %rax + cmp %rcx, %rax + sete %al + movsbq %al, %rax + pushq %rax + popq %rax + test %rax, %rax + jz 22f + .section .rodata +24: + .string "yes" + .text + movq $24b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf +22: + .section .rodata +25: + .string "\n" + .text + movq $25b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq scanner_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "abbc1d1d2\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/scan1_c.rl b/test/trans.d/case/scan1_c.rl new file mode 100644 index 00000000..5ecbf243 --- /dev/null +++ b/test/trans.d/case/scan1_c.rl @@ -0,0 +1,114 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char * ts ; +char * te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%s", "on last " ); +if ( p + 1 == te ) +{ + printf( "%s", "yes" ); + +} +printf( "%s", "\n" ); +}; + + 'b'+ => {printf( "%s", "on next " ); +if ( p + 1 == te ) +{ + printf( "%s", "yes" ); + +} +printf( "%s", "\n" ); +}; + + 'c1' 'dxxx'? => {printf( "%s", "on lag " ); +if ( p + 1 == te ) +{ + printf( "%s", "yes" ); + +} +printf( "%s", "\n" ); +}; + + 'd1' => {printf( "%s", "lm switch1 " ); +if ( p + 1 == te ) +{ + printf( "%s", "yes" ); + +} +printf( "%s", "\n" ); +}; + 'd2' => {printf( "%s", "lm switch2 " ); +if ( p + 1 == te ) +{ + printf( "%s", "yes" ); + +} +printf( "%s", "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"abbc1d1d2\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan1_crack.rl b/test/trans.d/case/scan1_crack.rl new file mode 100644 index 00000000..c2d9de1a --- /dev/null +++ b/test/trans.d/case/scan1_crack.rl @@ -0,0 +1,101 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int + ts; +int + te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {cout.format( "on last " ); +if ( p + 1 == te ) +{ + cout.format( "yes" ); + +} +cout.format( "\n" ); +}; + + 'b'+ => {cout.format( "on next " ); +if ( p + 1 == te ) +{ + cout.format( "yes" ); + +} +cout.format( "\n" ); +}; + + 'c1' 'dxxx'? => {cout.format( "on lag " ); +if ( p + 1 == te ) +{ + cout.format( "yes" ); + +} +cout.format( "\n" ); +}; + + 'd1' => {cout.format( "lm switch1 " ); +if ( p + 1 == te ) +{ + cout.format( "yes" ); + +} +cout.format( "\n" ); +}; + 'd2' => {cout.format( "lm switch2 " ); +if ( p + 1 == te ) +{ + cout.format( "yes" ); + +} +cout.format( "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "abbc1d1d2\n" ); +} + +main(); diff --git a/test/trans.d/case/scan1_cs.rl b/test/trans.d/case/scan1_cs.rl new file mode 100644 index 00000000..7f5a98f6 --- /dev/null +++ b/test/trans.d/case/scan1_cs.rl @@ -0,0 +1,103 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int ts; +int te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {Console.Write( "on last " );if ( p + 1 == te ) +{ + Console.Write( "yes" ); +} +Console.Write( "\n" );}; + + 'b'+ => {Console.Write( "on next " );if ( p + 1 == te ) +{ + Console.Write( "yes" ); +} +Console.Write( "\n" );}; + + 'c1' 'dxxx'? => {Console.Write( "on lag " );if ( p + 1 == te ) +{ + Console.Write( "yes" ); +} +Console.Write( "\n" );}; + + 'd1' => {Console.Write( "lm switch1 " );if ( p + 1 == te ) +{ + Console.Write( "yes" ); +} +Console.Write( "\n" );}; + 'd2' => {Console.Write( "lm switch2 " );if ( p + 1 == te ) +{ + Console.Write( "yes" ); +} +Console.Write( "\n" );}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"abbc1d1d2\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/scan1_d.rl b/test/trans.d/case/scan1_d.rl new file mode 100644 index 00000000..adbcb66d --- /dev/null +++ b/test/trans.d/case/scan1_d.rl @@ -0,0 +1,103 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class scanner +{ +const(char) * ts; +const(char) * te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%.*s", "on last " );if ( p + 1 == te ) +{ + printf( "%.*s", "yes" ); +} +printf( "%.*s", "\n" );}; + + 'b'+ => {printf( "%.*s", "on next " );if ( p + 1 == te ) +{ + printf( "%.*s", "yes" ); +} +printf( "%.*s", "\n" );}; + + 'c1' 'dxxx'? => {printf( "%.*s", "on lag " );if ( p + 1 == te ) +{ + printf( "%.*s", "yes" ); +} +printf( "%.*s", "\n" );}; + + 'd1' => {printf( "%.*s", "lm switch1 " );if ( p + 1 == te ) +{ + printf( "%.*s", "yes" ); +} +printf( "%.*s", "\n" );}; + 'd2' => {printf( "%.*s", "lm switch2 " );if ( p + 1 == te ) +{ + printf( "%.*s", "yes" ); +} +printf( "%.*s", "\n" );}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"abbc1d1d2\n", +]; + +int inplen = 1; + +} +int main() +{ + scanner m = new scanner(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan1_go.rl b/test/trans.d/case/scan1_go.rl new file mode 100644 index 00000000..66ca5f0c --- /dev/null +++ b/test/trans.d/case/scan1_go.rl @@ -0,0 +1,84 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var ts int ; +var te int ; +var act int ; +var token int ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {fmt.Print( "on last " );if ( p + 1 == te ) { + fmt.Print( "yes" ); +} +fmt.Print( "\n" );}; + + 'b'+ => {fmt.Print( "on next " );if ( p + 1 == te ) { + fmt.Print( "yes" ); +} +fmt.Print( "\n" );}; + + 'c1' 'dxxx'? => {fmt.Print( "on lag " );if ( p + 1 == te ) { + fmt.Print( "yes" ); +} +fmt.Print( "\n" );}; + + 'd1' => {fmt.Print( "lm switch1 " );if ( p + 1 == te ) { + fmt.Print( "yes" ); +} +fmt.Print( "\n" );}; + 'd2' => {fmt.Print( "lm switch2 " );if ( p + 1 == te ) { + fmt.Print( "yes" ); +} +fmt.Print( "\n" );}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= scanner_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"abbc1d1d2\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/scan1_java.rl b/test/trans.d/case/scan1_java.rl new file mode 100644 index 00000000..93562703 --- /dev/null +++ b/test/trans.d/case/scan1_java.rl @@ -0,0 +1,117 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class scan1_java +{ +int + ts ; +int + te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {System.out.print( "on last " ); +if ( p + 1 == te ) +{ + System.out.print( "yes" ); + +} +System.out.print( "\n" ); +}; + + 'b'+ => {System.out.print( "on next " ); +if ( p + 1 == te ) +{ + System.out.print( "yes" ); + +} +System.out.print( "\n" ); +}; + + 'c1' 'dxxx'? => {System.out.print( "on lag " ); +if ( p + 1 == te ) +{ + System.out.print( "yes" ); + +} +System.out.print( "\n" ); +}; + + 'd1' => {System.out.print( "lm switch1 " ); +if ( p + 1 == te ) +{ + System.out.print( "yes" ); + +} +System.out.print( "\n" ); +}; + 'd2' => {System.out.print( "lm switch2 " ); +if ( p + 1 == te ) +{ + System.out.print( "yes" ); + +} +System.out.print( "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"abbc1d1d2\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + scan1_java machine = new scan1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/scan1_julia.rl b/test/trans.d/case/scan1_julia.rl new file mode 100644 index 00000000..537e22c3 --- /dev/null +++ b/test/trans.d/case/scan1_julia.rl @@ -0,0 +1,83 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "on last " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'b'+ => {print( "on next " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'c1' 'dxxx'? => {print( "on lag " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'd1' => {print( "lm switch1 " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + 'd2' => {print( "lm switch2 " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +ts = 0; +te = 0; +act = 0; +token = 0; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "abbc1d1d2\n" ); diff --git a/test/trans.d/case/scan1_ocaml.rl b/test/trans.d/case/scan1_ocaml.rl new file mode 100644 index 00000000..d3a156e6 --- /dev/null +++ b/test/trans.d/case/scan1_ocaml.rl @@ -0,0 +1,96 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let token = ref 0 + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print_string( "on last " ); +if p.contents + 1 == te .contents then +begin + print_string( "yes" ); + +end +; +print_string( "\n" ); +}; + + 'b'+ => {print_string( "on next " ); +if p.contents + 1 == te .contents then +begin + print_string( "yes" ); + +end +; +print_string( "\n" ); +}; + + 'c1' 'dxxx'? => {print_string( "on lag " ); +if p.contents + 1 == te .contents then +begin + print_string( "yes" ); + +end +; +print_string( "\n" ); +}; + + 'd1' => {print_string( "lm switch1 " ); +if p.contents + 1 == te .contents then +begin + print_string( "yes" ); + +end +; +print_string( "\n" ); +}; + 'd2' => {print_string( "lm switch2 " ); +if p.contents + 1 == te .contents then +begin + print_string( "yes" ); + +end +; +print_string( "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= scanner_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "abbc1d1d2\n"; + () +;; + diff --git a/test/trans.d/case/scan1_ruby.rl b/test/trans.d/case/scan1_ruby.rl new file mode 100644 index 00000000..3c983fe5 --- /dev/null +++ b/test/trans.d/case/scan1_ruby.rl @@ -0,0 +1,91 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "on last " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'b'+ => {print( "on next " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'c1' 'dxxx'? => {print( "on lag " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + 'd1' => {print( "lm switch1 " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + 'd2' => {print( "lm switch2 " ); +if ( p + 1 == te ) + print( "yes" ); + +end +print( "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +ts = 1 +te = 1 +act = 1 +token = 1 + %% write init; + %% write exec; + if cs >= scanner_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"abbc1d1d2\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/scan1_rust.rl b/test/trans.d/case/scan1_rust.rl new file mode 100644 index 00000000..aa67bcd5 --- /dev/null +++ b/test/trans.d/case/scan1_rust.rl @@ -0,0 +1,97 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut token : i32 = 0; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print!( "{}", "on last " ); +if ( p + 1 == te ) +{ + print!( "{}", "yes" ); + +} +print!( "{}", "\n" ); +}; + + 'b'+ => {print!( "{}", "on next " ); +if ( p + 1 == te ) +{ + print!( "{}", "yes" ); + +} +print!( "{}", "\n" ); +}; + + 'c1' 'dxxx'? => {print!( "{}", "on lag " ); +if ( p + 1 == te ) +{ + print!( "{}", "yes" ); + +} +print!( "{}", "\n" ); +}; + + 'd1' => {print!( "{}", "lm switch1 " ); +if ( p + 1 == te ) +{ + print!( "{}", "yes" ); + +} +print!( "{}", "\n" ); +}; + 'd2' => {print!( "{}", "lm switch2 " ); +if ( p + 1 == te ) +{ + print!( "{}", "yes" ); + +} +print!( "{}", "\n" ); +}; + + [d0-9]+ '.'; + + '\n'; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "abbc1d1d2\n".to_string() ); } +} + diff --git a/test/trans.d/case/scan2.rl b/test/trans.d/case/scan2.rl new file mode 100644 index 00000000..167b2c8c --- /dev/null +++ b/test/trans.d/case/scan2.rl @@ -0,0 +1,34 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ +ptr ts; +ptr te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + print_str "pat1\n"; + }; + + [ab]+ . 'c' => { + print_str "pat2\n"; + }; + + any => { + print_str "any\n"; + }; + *|; +}%% + +##### INPUT ##### +"a" +##### OUTPUT ##### +pat1 +ACCEPT diff --git a/test/trans.d/case/scan2_asm.rl b/test/trans.d/case/scan2_asm.rl new file mode 100644 index 00000000..72500c64 --- /dev/null +++ b/test/trans.d/case/scan2_asm.rl @@ -0,0 +1,168 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm token,8,8 + .text + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + .section .rodata +1: + .string "pat1\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + [ab]+ . 'c' => { + .section .rodata +2: + .string "pat2\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + any => { + .section .rodata +3: + .string "any\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq scanner_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "a" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/scan2_c.rl b/test/trans.d/case/scan2_c.rl new file mode 100644 index 00000000..61638e8f --- /dev/null +++ b/test/trans.d/case/scan2_c.rl @@ -0,0 +1,75 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char * ts ; +char * te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%s", "pat1\n" ); +}; + + [ab]+ . 'c' => {printf( "%s", "pat2\n" ); +}; + + any => {printf( "%s", "any\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"a", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan2_crack.rl b/test/trans.d/case/scan2_crack.rl new file mode 100644 index 00000000..dcc88144 --- /dev/null +++ b/test/trans.d/case/scan2_crack.rl @@ -0,0 +1,62 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int + ts; +int + te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {cout.format( "pat1\n" ); +}; + + [ab]+ . 'c' => {cout.format( "pat2\n" ); +}; + + any => {cout.format( "any\n" ); +}; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "a" ); +} + +main(); diff --git a/test/trans.d/case/scan2_cs.rl b/test/trans.d/case/scan2_cs.rl new file mode 100644 index 00000000..b49e6ef2 --- /dev/null +++ b/test/trans.d/case/scan2_cs.rl @@ -0,0 +1,76 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int ts; +int te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {Console.Write( "pat1\n" );}; + + [ab]+ . 'c' => {Console.Write( "pat2\n" );}; + + any => {Console.Write( "any\n" );}; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"a", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/scan2_d.rl b/test/trans.d/case/scan2_d.rl new file mode 100644 index 00000000..79a6eda5 --- /dev/null +++ b/test/trans.d/case/scan2_d.rl @@ -0,0 +1,76 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class scanner +{ +const(char) * ts; +const(char) * te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%.*s", "pat1\n" );}; + + [ab]+ . 'c' => {printf( "%.*s", "pat2\n" );}; + + any => {printf( "%.*s", "any\n" );}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"a", +]; + +int inplen = 1; + +} +int main() +{ + scanner m = new scanner(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan2_go.rl b/test/trans.d/case/scan2_go.rl new file mode 100644 index 00000000..d52c4e39 --- /dev/null +++ b/test/trans.d/case/scan2_go.rl @@ -0,0 +1,62 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var ts int ; +var te int ; +var act int ; +var token int ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {fmt.Print( "pat1\n" );}; + + [ab]+ . 'c' => {fmt.Print( "pat2\n" );}; + + any => {fmt.Print( "any\n" );}; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= scanner_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"a", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/scan2_java.rl b/test/trans.d/case/scan2_java.rl new file mode 100644 index 00000000..eb07ac70 --- /dev/null +++ b/test/trans.d/case/scan2_java.rl @@ -0,0 +1,78 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class scan2_java +{ +int + ts ; +int + te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {System.out.print( "pat1\n" ); +}; + + [ab]+ . 'c' => {System.out.print( "pat2\n" ); +}; + + any => {System.out.print( "any\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"a", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + scan2_java machine = new scan2_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/scan2_julia.rl b/test/trans.d/case/scan2_julia.rl new file mode 100644 index 00000000..2d0c095e --- /dev/null +++ b/test/trans.d/case/scan2_julia.rl @@ -0,0 +1,49 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + + [ab]+ . 'c' => {print( "pat2\n" ); +}; + + any => {print( "any\n" ); +}; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +ts = 0; +te = 0; +act = 0; +token = 0; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "a" ); diff --git a/test/trans.d/case/scan2_ocaml.rl b/test/trans.d/case/scan2_ocaml.rl new file mode 100644 index 00000000..c43e5547 --- /dev/null +++ b/test/trans.d/case/scan2_ocaml.rl @@ -0,0 +1,52 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let token = ref 0 + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print_string( "pat1\n" ); +}; + + [ab]+ . 'c' => {print_string( "pat2\n" ); +}; + + any => {print_string( "any\n" ); +}; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= scanner_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "a"; + () +;; + diff --git a/test/trans.d/case/scan2_ruby.rl b/test/trans.d/case/scan2_ruby.rl new file mode 100644 index 00000000..ba082b3f --- /dev/null +++ b/test/trans.d/case/scan2_ruby.rl @@ -0,0 +1,57 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + + [ab]+ . 'c' => {print( "pat2\n" ); +}; + + any => {print( "any\n" ); +}; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +ts = 1 +te = 1 +act = 1 +token = 1 + %% write init; + %% write exec; + if cs >= scanner_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"a", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/scan2_rust.rl b/test/trans.d/case/scan2_rust.rl new file mode 100644 index 00000000..c0ef13ae --- /dev/null +++ b/test/trans.d/case/scan2_rust.rl @@ -0,0 +1,58 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut token : i32 = 0; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print!( "{}", "pat1\n" ); +}; + + [ab]+ . 'c' => {print!( "{}", "pat2\n" ); +}; + + any => {print!( "{}", "any\n" ); +}; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "a".to_string() ); } +} + diff --git a/test/trans.d/case/scan3.rl b/test/trans.d/case/scan3.rl new file mode 100644 index 00000000..80ab4815 --- /dev/null +++ b/test/trans.d/case/scan3.rl @@ -0,0 +1,33 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +ptr ts; +ptr te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + print_str "pat1\n"; + }; + 'b' => { + print_str "pat2\n"; + }; + [ab] any* => { + print_str "pat3\n"; + }; + *|; +}%% + +##### INPUT ##### +"ab89" +##### OUTPUT ##### +pat3 +ACCEPT diff --git a/test/trans.d/case/scan3_asm.rl b/test/trans.d/case/scan3_asm.rl new file mode 100644 index 00000000..0f95a1e3 --- /dev/null +++ b/test/trans.d/case/scan3_asm.rl @@ -0,0 +1,166 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm token,8,8 + .text + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + .section .rodata +1: + .string "pat1\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + 'b' => { + .section .rodata +2: + .string "pat2\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + [ab] any* => { + .section .rodata +3: + .string "pat3\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq scanner_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "ab89" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/scan3_c.rl b/test/trans.d/case/scan3_c.rl new file mode 100644 index 00000000..ccd0fcea --- /dev/null +++ b/test/trans.d/case/scan3_c.rl @@ -0,0 +1,73 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char * ts ; +char * te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%s", "pat1\n" ); +}; + 'b' => {printf( "%s", "pat2\n" ); +}; + [ab] any* => {printf( "%s", "pat3\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"ab89", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan3_crack.rl b/test/trans.d/case/scan3_crack.rl new file mode 100644 index 00000000..8fbc734e --- /dev/null +++ b/test/trans.d/case/scan3_crack.rl @@ -0,0 +1,60 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int + ts; +int + te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {cout.format( "pat1\n" ); +}; + 'b' => {cout.format( "pat2\n" ); +}; + [ab] any* => {cout.format( "pat3\n" ); +}; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "ab89" ); +} + +main(); diff --git a/test/trans.d/case/scan3_cs.rl b/test/trans.d/case/scan3_cs.rl new file mode 100644 index 00000000..0a802b65 --- /dev/null +++ b/test/trans.d/case/scan3_cs.rl @@ -0,0 +1,74 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int ts; +int te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {Console.Write( "pat1\n" );}; + 'b' => {Console.Write( "pat2\n" );}; + [ab] any* => {Console.Write( "pat3\n" );}; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"ab89", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/scan3_d.rl b/test/trans.d/case/scan3_d.rl new file mode 100644 index 00000000..334d9291 --- /dev/null +++ b/test/trans.d/case/scan3_d.rl @@ -0,0 +1,74 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class scanner +{ +const(char) * ts; +const(char) * te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%.*s", "pat1\n" );}; + 'b' => {printf( "%.*s", "pat2\n" );}; + [ab] any* => {printf( "%.*s", "pat3\n" );}; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"ab89", +]; + +int inplen = 1; + +} +int main() +{ + scanner m = new scanner(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan3_go.rl b/test/trans.d/case/scan3_go.rl new file mode 100644 index 00000000..4bc7363f --- /dev/null +++ b/test/trans.d/case/scan3_go.rl @@ -0,0 +1,60 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var ts int ; +var te int ; +var act int ; +var token int ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {fmt.Print( "pat1\n" );}; + 'b' => {fmt.Print( "pat2\n" );}; + [ab] any* => {fmt.Print( "pat3\n" );}; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= scanner_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"ab89", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/scan3_java.rl b/test/trans.d/case/scan3_java.rl new file mode 100644 index 00000000..b4caad5d --- /dev/null +++ b/test/trans.d/case/scan3_java.rl @@ -0,0 +1,76 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class scan3_java +{ +int + ts ; +int + te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {System.out.print( "pat1\n" ); +}; + 'b' => {System.out.print( "pat2\n" ); +}; + [ab] any* => {System.out.print( "pat3\n" ); +}; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"ab89", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + scan3_java machine = new scan3_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/scan3_julia.rl b/test/trans.d/case/scan3_julia.rl new file mode 100644 index 00000000..c79e3c42 --- /dev/null +++ b/test/trans.d/case/scan3_julia.rl @@ -0,0 +1,47 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + 'b' => {print( "pat2\n" ); +}; + [ab] any* => {print( "pat3\n" ); +}; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +ts = 0; +te = 0; +act = 0; +token = 0; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "ab89" ); diff --git a/test/trans.d/case/scan3_ocaml.rl b/test/trans.d/case/scan3_ocaml.rl new file mode 100644 index 00000000..fb783612 --- /dev/null +++ b/test/trans.d/case/scan3_ocaml.rl @@ -0,0 +1,50 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let token = ref 0 + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print_string( "pat1\n" ); +}; + 'b' => {print_string( "pat2\n" ); +}; + [ab] any* => {print_string( "pat3\n" ); +}; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= scanner_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "ab89"; + () +;; + diff --git a/test/trans.d/case/scan3_ruby.rl b/test/trans.d/case/scan3_ruby.rl new file mode 100644 index 00000000..dc104d8f --- /dev/null +++ b/test/trans.d/case/scan3_ruby.rl @@ -0,0 +1,55 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + 'b' => {print( "pat2\n" ); +}; + [ab] any* => {print( "pat3\n" ); +}; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +ts = 1 +te = 1 +act = 1 +token = 1 + %% write init; + %% write exec; + if cs >= scanner_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"ab89", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/scan3_rust.rl b/test/trans.d/case/scan3_rust.rl new file mode 100644 index 00000000..f8644ad1 --- /dev/null +++ b/test/trans.d/case/scan3_rust.rl @@ -0,0 +1,56 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut token : i32 = 0; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print!( "{}", "pat1\n" ); +}; + 'b' => {print!( "{}", "pat2\n" ); +}; + [ab] any* => {print!( "{}", "pat3\n" ); +}; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "ab89".to_string() ); } +} + diff --git a/test/trans.d/case/scan4.rl b/test/trans.d/case/scan4.rl new file mode 100644 index 00000000..44f24b16 --- /dev/null +++ b/test/trans.d/case/scan4.rl @@ -0,0 +1,34 @@ +/* + * @LANG: indep + * @NEEDS_EOF: yes + */ + +ptr ts; +ptr te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + print_str "pat1\n"; + }; + + [ab]+ . 'c' => { + print_str "pat2\n"; + }; + + any; + *|; +}%% + +##### INPUT ##### +"ba a" +##### OUTPUT ##### +pat1 +pat1 +ACCEPT diff --git a/test/trans.d/case/scan4_asm.rl b/test/trans.d/case/scan4_asm.rl new file mode 100644 index 00000000..fe31624e --- /dev/null +++ b/test/trans.d/case/scan4_asm.rl @@ -0,0 +1,156 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm ts,8,8 + .text + .section .data + .comm te,8,8 + .text + .section .data + .comm act,8,8 + .text + .section .data + .comm token,8,8 + .text + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => { + .section .rodata +1: + .string "pat1\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + [ab]+ . 'c' => { + .section .rodata +2: + .string "pat2\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +}; + + any; + *|; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + movq %r13, -8(%rbp) + + %% write init; + %% write exec; + + # current state is in r11. + movq scanner_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "ba a" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/scan4_c.rl b/test/trans.d/case/scan4_c.rl new file mode 100644 index 00000000..16156454 --- /dev/null +++ b/test/trans.d/case/scan4_c.rl @@ -0,0 +1,74 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +char * ts ; +char * te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%s", "pat1\n" ); +}; + + [ab]+ . 'c' => {printf( "%s", "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + char *eof = pe; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"ba a", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan4_crack.rl b/test/trans.d/case/scan4_crack.rl new file mode 100644 index 00000000..5b3df31a --- /dev/null +++ b/test/trans.d/case/scan4_crack.rl @@ -0,0 +1,61 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int + ts; +int + te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {cout.format( "pat1\n" ); +}; + + [ab]+ . 'c' => {cout.format( "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + int eof = pe; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "ba a" ); +} + +main(); diff --git a/test/trans.d/case/scan4_cs.rl b/test/trans.d/case/scan4_cs.rl new file mode 100644 index 00000000..d0c4ad2c --- /dev/null +++ b/test/trans.d/case/scan4_cs.rl @@ -0,0 +1,76 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int ts; +int te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {Console.Write( "pat1\n" );}; + + [ab]+ . 'c' => {Console.Write( "pat2\n" );}; + + any; + *|; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"ba a", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/scan4_d.rl b/test/trans.d/case/scan4_d.rl new file mode 100644 index 00000000..4e942a3c --- /dev/null +++ b/test/trans.d/case/scan4_d.rl @@ -0,0 +1,76 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class scanner +{ +const(char) * ts; +const(char) * te; +int act; +int token; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {printf( "%.*s", "pat1\n" );}; + + [ab]+ . 'c' => {printf( "%.*s", "pat2\n" );}; + + any; + *|; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + const(char) *eof = pe; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"ba a", +]; + +int inplen = 1; + +} +int main() +{ + scanner m = new scanner(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/scan4_go.rl b/test/trans.d/case/scan4_go.rl new file mode 100644 index 00000000..bb7ee8bd --- /dev/null +++ b/test/trans.d/case/scan4_go.rl @@ -0,0 +1,62 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var ts int ; +var te int ; +var act int ; +var token int ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {fmt.Print( "pat1\n" );}; + + [ab]+ . 'c' => {fmt.Print( "pat2\n" );}; + + any; + *|; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + var eof int = pe + %% write exec; +} +func finish() { + if cs >= scanner_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"ba a", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/scan4_java.rl b/test/trans.d/case/scan4_java.rl new file mode 100644 index 00000000..852676d9 --- /dev/null +++ b/test/trans.d/case/scan4_java.rl @@ -0,0 +1,77 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class scan4_java +{ +int + ts ; +int + te ; +int act ; +int token ; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {System.out.print( "pat1\n" ); +}; + + [ab]+ . 'c' => {System.out.print( "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + int eof = len; + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= scanner_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"ba a", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + scan4_java machine = new scan4_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/scan4_julia.rl b/test/trans.d/case/scan4_julia.rl new file mode 100644 index 00000000..f23b5efa --- /dev/null +++ b/test/trans.d/case/scan4_julia.rl @@ -0,0 +1,48 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + + [ab]+ . 'c' => {print( "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +ts = 0; +te = 0; +act = 0; +token = 0; + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "ba a" ); diff --git a/test/trans.d/case/scan4_ocaml.rl b/test/trans.d/case/scan4_ocaml.rl new file mode 100644 index 00000000..21e13be8 --- /dev/null +++ b/test/trans.d/case/scan4_ocaml.rl @@ -0,0 +1,51 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let ts = ref 0 +let te = ref 0 +let act = ref 0 +let token = ref 0 + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print_string( "pat1\n" ); +}; + + [ab]+ . 'c' => {print_string( "pat2\n" ); +}; + + any; + *|; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + let eof = pe in + %% write init; + %% write exec; + if !cs >= scanner_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "ba a"; + () +;; + diff --git a/test/trans.d/case/scan4_ruby.rl b/test/trans.d/case/scan4_ruby.rl new file mode 100644 index 00000000..3fd484ce --- /dev/null +++ b/test/trans.d/case/scan4_ruby.rl @@ -0,0 +1,56 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print( "pat1\n" ); +}; + + [ab]+ . 'c' => {print( "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +ts = 1 +te = 1 +act = 1 +token = 1 + %% write init; + %% write exec; + if cs >= scanner_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"ba a", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/scan4_rust.rl b/test/trans.d/case/scan4_rust.rl new file mode 100644 index 00000000..84e03aea --- /dev/null +++ b/test/trans.d/case/scan4_rust.rl @@ -0,0 +1,57 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut ts : i32 + = 0; +static mut te : i32 + = 0; +static mut act : i32 = 0; +static mut token : i32 = 0; + +%%{ + machine scanner; + + # Warning: changing the patterns or the input string will affect the + # coverage of the scanner action types. + main := |* + 'a' => {print!( "{}", "pat1\n" ); +}; + + [ab]+ . 'c' => {print!( "{}", "pat2\n" ); +}; + + any; + *|; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= scanner_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "ba a".to_string() ); } +} + diff --git a/test/trans.d/case/stateact1.rl b/test/trans.d/case/stateact1.rl new file mode 100644 index 00000000..e5878b7c --- /dev/null +++ b/test/trans.d/case/stateact1.rl @@ -0,0 +1,47 @@ +/* + * @LANG: indep + * + * Test in and out state actions. + */ + +%%{ + machine state_act; + + action a1 { print_str "a1\n"; } + action a2 { print_str "a2\n"; } + action b1 { print_str "b1\n"; } + action b2 { print_str "b2\n"; } + action c1 { print_str "c1\n"; } + action c2 { print_str "c2\n"; } + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + +##### INPUT ##### + +"hi\nhi\n" + +##### OUTPUT ##### +a2 +b2 +c1 +c2 +b1 +b2 +c1 +c2 +b1 +FAIL diff --git a/test/trans.d/case/stateact1_asm.rl b/test/trans.d/case/stateact1_asm.rl new file mode 100644 index 00000000..1d2f9486 --- /dev/null +++ b/test/trans.d/case/stateact1_asm.rl @@ -0,0 +1,208 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine state_act; + + action a1 { + .section .rodata +1: + .string "a1\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action a2 { + .section .rodata +2: + .string "a2\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action b1 { + .section .rodata +3: + .string "b1\n" + .text + movq $3b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action b2 { + .section .rodata +4: + .string "b2\n" + .text + movq $4b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action c1 { + .section .rodata +5: + .string "c1\n" + .text + movq $5b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action c2 { + .section .rodata +6: + .string "c2\n" + .text + movq $6b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + +} + action next_again { + fnext again; + +} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq state_act_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "hi\nhi\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/stateact1_c.rl b/test/trans.d/case/stateact1_c.rl new file mode 100644 index 00000000..3f6bc0fa --- /dev/null +++ b/test/trans.d/case/stateact1_c.rl @@ -0,0 +1,87 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine state_act; + + action a1 {printf( "%s", "a1\n" ); +} + action a2 {printf( "%s", "a2\n" ); +} + action b1 {printf( "%s", "b1\n" ); +} + action b2 {printf( "%s", "b2\n" ); +} + action c1 {printf( "%s", "c1\n" ); +} + action c2 {printf( "%s", "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_act_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"hi\nhi\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/stateact1_crack.rl b/test/trans.d/case/stateact1_crack.rl new file mode 100644 index 00000000..3bdb22aa --- /dev/null +++ b/test/trans.d/case/stateact1_crack.rl @@ -0,0 +1,72 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine state_act; + + action a1 {cout.format( "a1\n" ); +} + action a2 {cout.format( "a2\n" ); +} + action b1 {cout.format( "b1\n" ); +} + action b2 {cout.format( "b2\n" ); +} + action c1 {cout.format( "c1\n" ); +} + action c2 {cout.format( "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= state_act_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "hi\nhi\n" ); +} + +main(); diff --git a/test/trans.d/case/stateact1_cs.rl b/test/trans.d/case/stateact1_cs.rl new file mode 100644 index 00000000..d2d37010 --- /dev/null +++ b/test/trans.d/case/stateact1_cs.rl @@ -0,0 +1,86 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine state_act; + + action a1 {Console.Write( "a1\n" );} + action a2 {Console.Write( "a2\n" );} + action b1 {Console.Write( "b1\n" );} + action b2 {Console.Write( "b2\n" );} + action c1 {Console.Write( "c1\n" );} + action c2 {Console.Write( "c2\n" );} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_act_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"hi\nhi\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/stateact1_d.rl b/test/trans.d/case/stateact1_d.rl new file mode 100644 index 00000000..fb728430 --- /dev/null +++ b/test/trans.d/case/stateact1_d.rl @@ -0,0 +1,85 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class state_act +{ + + + +%%{ + machine state_act; + + action a1 {printf( "%.*s", "a1\n" );} + action a2 {printf( "%.*s", "a2\n" );} + action b1 {printf( "%.*s", "b1\n" );} + action b2 {printf( "%.*s", "b2\n" );} + action c1 {printf( "%.*s", "c1\n" );} + action c2 {printf( "%.*s", "c2\n" );} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_act_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"hi\nhi\n", +]; + +int inplen = 1; + +} +int main() +{ + state_act m = new state_act(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/stateact1_go.rl b/test/trans.d/case/stateact1_go.rl new file mode 100644 index 00000000..3514bbc7 --- /dev/null +++ b/test/trans.d/case/stateact1_go.rl @@ -0,0 +1,72 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine state_act; + + action a1 {fmt.Print( "a1\n" );} + action a2 {fmt.Print( "a2\n" );} + action b1 {fmt.Print( "b1\n" );} + action b2 {fmt.Print( "b2\n" );} + action c1 {fmt.Print( "c1\n" );} + action c2 {fmt.Print( "c2\n" );} + action next_again {fnext again; +} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= state_act_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"hi\nhi\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/stateact1_java.rl b/test/trans.d/case/stateact1_java.rl new file mode 100644 index 00000000..3b94ecf0 --- /dev/null +++ b/test/trans.d/case/stateact1_java.rl @@ -0,0 +1,88 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class stateact1_java +{ + + + +%%{ + machine state_act; + + action a1 {System.out.print( "a1\n" ); +} + action a2 {System.out.print( "a2\n" ); +} + action b1 {System.out.print( "b1\n" ); +} + action b2 {System.out.print( "b2\n" ); +} + action c1 {System.out.print( "c1\n" ); +} + action c2 {System.out.print( "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= state_act_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"hi\nhi\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + stateact1_java machine = new stateact1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/stateact1_julia.rl b/test/trans.d/case/stateact1_julia.rl new file mode 100644 index 00000000..b750493d --- /dev/null +++ b/test/trans.d/case/stateact1_julia.rl @@ -0,0 +1,62 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine state_act; + + action a1 {print( "a1\n" ); +} + action a2 {print( "a2\n" ); +} + action b1 {print( "b1\n" ); +} + action b2 {print( "b2\n" ); +} + action c1 {print( "c1\n" ); +} + action c2 {print( "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= state_act_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "hi\nhi\n" ); diff --git a/test/trans.d/case/stateact1_ocaml.rl b/test/trans.d/case/stateact1_ocaml.rl new file mode 100644 index 00000000..86371297 --- /dev/null +++ b/test/trans.d/case/stateact1_ocaml.rl @@ -0,0 +1,64 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine state_act; + + action a1 {print_string( "a1\n" ); +} + action a2 {print_string( "a2\n" ); +} + action b1 {print_string( "b1\n" ); +} + action b2 {print_string( "b2\n" ); +} + action c1 {print_string( "c1\n" ); +} + action c2 {print_string( "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= state_act_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "hi\nhi\n"; + () +;; + diff --git a/test/trans.d/case/stateact1_ruby.rl b/test/trans.d/case/stateact1_ruby.rl new file mode 100644 index 00000000..d8ecb208 --- /dev/null +++ b/test/trans.d/case/stateact1_ruby.rl @@ -0,0 +1,70 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine state_act; + + action a1 {print( "a1\n" ); +} + action a2 {print( "a2\n" ); +} + action b1 {print( "b1\n" ); +} + action b2 {print( "b2\n" ); +} + action c1 {print( "c1\n" ); +} + action c2 {print( "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= state_act_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"hi\nhi\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/stateact1_rust.rl b/test/trans.d/case/stateact1_rust.rl new file mode 100644 index 00000000..f723f96a --- /dev/null +++ b/test/trans.d/case/stateact1_rust.rl @@ -0,0 +1,69 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine state_act; + + action a1 {print!( "{}", "a1\n" ); +} + action a2 {print!( "{}", "a2\n" ); +} + action b1 {print!( "{}", "b1\n" ); +} + action b2 {print!( "{}", "b2\n" ); +} + action c1 {print!( "{}", "c1\n" ); +} + action c2 {print!( "{}", "c2\n" ); +} + action next_again {fnext again;} + + hi = 'hi'; + line = again: + hi + >to b1 + >from b2 + '\n' + >to c1 + >from c2 + @next_again; + + main := line* + >to a1 + >from a2; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= state_act_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "hi\nhi\n".to_string() ); } +} + diff --git a/test/trans.d/case/targs1.rl b/test/trans.d/case/targs1.rl new file mode 100644 index 00000000..b97a550e --- /dev/null +++ b/test/trans.d/case/targs1.rl @@ -0,0 +1,35 @@ +/* + * @LANG: indep + */ + +int return_to; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{ + print_str "one\n"; + fnext *return_to; + }; + + two := 'two' @{ + print_str "two\n"; + fnext *return_to; + }; + + main := ( + '1' @{ return_to = ftargs; fnext one; } + | '2' @{ return_to = ftargs; fnext two; } + | '\n' + )*; +}%% + +##### INPUT ##### +"1one2two1one\n" +##### OUTPUT ##### +one +two +one +ACCEPT diff --git a/test/trans.d/case/targs1_asm.rl b/test/trans.d/case/targs1_asm.rl new file mode 100644 index 00000000..7d4df5f6 --- /dev/null +++ b/test/trans.d/case/targs1_asm.rl @@ -0,0 +1,172 @@ +# +# @LANG: asm +# @GENERATED: true +# + + .section .data + .comm return_to,8,8 + .text + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{ + .section .rodata +1: + .string "one\n" + .text + movq $1b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq return_to(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + two := 'two' @{ + .section .rodata +2: + .string "two\n" + .text + movq $2b, %rax + pushq %rax + movq $.L_fmt_str, %rdi + popq %rsi + movq $0, %rax + call printf + movq return_to(%rip), %rax + pushq %rax +movq $0, %rax +popq %rcx +fnext * %rcx; + +}; + + main := ( + '1' @{ + ftargs; + pushq %rax + popq %rax + movq %rax, return_to (%rip) +fnext one; + +} + | '2' @{ + ftargs; + pushq %rax + popq %rax + movq %rax, return_to (%rip) +fnext two; + +} + | '\n' + )*; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq targs1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "1one2two1one\n" + + .align 8 +inp: + .quad .L_inp_0 + + .align 8 +inplen: + .quad 1 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/targs1_c.rl b/test/trans.d/case/targs1_c.rl new file mode 100644 index 00000000..c0ae2539 --- /dev/null +++ b/test/trans.d/case/targs1_c.rl @@ -0,0 +1,74 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + +int return_to ; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{printf( "%s", "one\n" ); +fnext *return_to;}; + + two := 'two' @{printf( "%s", "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= targs1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"1one2two1one\n", +}; + +int inplen = 1; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/targs1_crack.rl b/test/trans.d/case/targs1_crack.rl new file mode 100644 index 00000000..ebd0036a --- /dev/null +++ b/test/trans.d/case/targs1_crack.rl @@ -0,0 +1,59 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + +int return_to; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{cout.format( "one\n" ); +fnext *return_to;}; + + two := 'two' @{cout.format( "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= targs1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "1one2two1one\n" ); +} + +main(); diff --git a/test/trans.d/case/targs1_cs.rl b/test/trans.d/case/targs1_cs.rl new file mode 100644 index 00000000..d655b7cd --- /dev/null +++ b/test/trans.d/case/targs1_cs.rl @@ -0,0 +1,77 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ +int return_to; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{Console.Write( "one\n" );fnext *return_to;}; + + two := 'two' @{Console.Write( "two\n" );fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= targs1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"1one2two1one\n", +}; + + +static readonly int inplen = 1; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/targs1_d.rl b/test/trans.d/case/targs1_d.rl new file mode 100644 index 00000000..82387206 --- /dev/null +++ b/test/trans.d/case/targs1_d.rl @@ -0,0 +1,76 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class targs1 +{ +int return_to; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{printf( "%.*s", "one\n" );fnext *return_to;}; + + two := 'two' @{printf( "%.*s", "two\n" );fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= targs1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"1one2two1one\n", +]; + +int inplen = 1; + +} +int main() +{ + targs1 m = new targs1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/targs1_go.rl b/test/trans.d/case/targs1_go.rl new file mode 100644 index 00000000..28d8de64 --- /dev/null +++ b/test/trans.d/case/targs1_go.rl @@ -0,0 +1,68 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + +var return_to int ; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{fmt.Print( "one\n" );fnext *return_to; + +}; + + two := 'two' @{fmt.Print( "two\n" );fnext *return_to; + +}; + + main := ( + '1' @{return_to = ftargs; +fnext one; +} + | '2' @{return_to = ftargs; +fnext two; +} + | '\n' + )*; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= targs1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"1one2two1one\n", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/targs1_java.rl b/test/trans.d/case/targs1_java.rl new file mode 100644 index 00000000..ddf2df9e --- /dev/null +++ b/test/trans.d/case/targs1_java.rl @@ -0,0 +1,75 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class targs1_java +{ +int return_to ; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{System.out.print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{System.out.print( "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= targs1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"1one2two1one\n", +}; + +static final int inplen = 1; + +public static void main (String[] args) +{ + targs1_java machine = new targs1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/targs1_julia.rl b/test/trans.d/case/targs1_julia.rl new file mode 100644 index 00000000..445d407e --- /dev/null +++ b/test/trans.d/case/targs1_julia.rl @@ -0,0 +1,49 @@ +// +// @LANG: julia +// @GENERATED: true +// + + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{print( "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" +return_to = 0; + + %% write init; + %% write exec; + + if ( cs >= targs1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "1one2two1one\n" ); diff --git a/test/trans.d/case/targs1_ocaml.rl b/test/trans.d/case/targs1_ocaml.rl new file mode 100644 index 00000000..9fd43577 --- /dev/null +++ b/test/trans.d/case/targs1_ocaml.rl @@ -0,0 +1,53 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + +let return_to = ref 0 + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{print_string( "one\n" ); +fnext *return_to.contents; +}; + + two := 'two' @{print_string( "two\n" ); +fnext *return_to.contents; +}; + + main := ( + '1' @{return_to := ftargs; +fnext one; } + | '2' @{return_to := ftargs; +fnext two; } + | '\n' + )*; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= targs1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec "1one2two1one\n"; + () +;; + diff --git a/test/trans.d/case/targs1_ruby.rl b/test/trans.d/case/targs1_ruby.rl new file mode 100644 index 00000000..afb64592 --- /dev/null +++ b/test/trans.d/case/targs1_ruby.rl @@ -0,0 +1,57 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{print( "one\n" ); +fnext *return_to;}; + + two := 'two' @{print( "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 +return_to = 1 + %% write init; + %% write exec; + if cs >= targs1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"1one2two1one\n", +] + +inplen = 1 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/targs1_rust.rl b/test/trans.d/case/targs1_rust.rl new file mode 100644 index 00000000..6fc75120 --- /dev/null +++ b/test/trans.d/case/targs1_rust.rl @@ -0,0 +1,56 @@ +// +// @LANG: rust +// @GENERATED: true +// + +static mut return_to : i32 = 0; + +%%{ + machine targs1; + + unused := 'unused'; + + one := 'one' @{print!( "{}", "one\n" ); +fnext *return_to;}; + + two := 'two' @{print!( "{}", "two\n" ); +fnext *return_to;}; + + main := ( + '1' @{return_to = ftargs; +fnext one;} + | '2' @{return_to = ftargs; +fnext two;} + | '\n' + )*; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= targs1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "1one2two1one\n".to_string() ); } +} + diff --git a/test/trans.d/case/zlen1.rl b/test/trans.d/case/zlen1.rl new file mode 100644 index 00000000..279818a0 --- /dev/null +++ b/test/trans.d/case/zlen1.rl @@ -0,0 +1,15 @@ +/* + * @LANG: indep + */ + +%%{ + machine zlen1; + main := zlen; +}%% + +##### INPUT ##### +"" +"x" +##### OUTPUT ##### +ACCEPT +FAIL diff --git a/test/trans.d/case/zlen1_asm.rl b/test/trans.d/case/zlen1_asm.rl new file mode 100644 index 00000000..a0e6e010 --- /dev/null +++ b/test/trans.d/case/zlen1_asm.rl @@ -0,0 +1,115 @@ +# +# @LANG: asm +# @GENERATED: true +# + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + + .text + .comm buf, 1024, 32 + .comm bpos, 8, 8 + .comm stack_data, 1024, 32 + .section .rodata + +.L_str_accept: + .string "ACCEPT" +.L_str_fail: + .string "FAIL" +.L_fmt_int: + .string "%ld" +.L_fmt_str: + .string "%s" + + %% write data; + + .text +exec: + pushq %rbp + movq %rsp, %rbp + subq $96, %rsp + + movq $stack_data, -56(%rbp) + + pushq %r12 + pushq %r13 + movq %rdi, %r12 + + # Get the length. + movq %r12, %rdi + call strlen + movq %r12, %r13 + movslq %eax, %rax + addq %rax, %r13 + + movq $0, bpos(%rip) + + %% write init; + %% write exec; + + # current state is in r11. + movq zlen1_first_final(%rip), %rax + cmpq %rax, %r11 + jl .L_exec_fail + movq $.L_str_accept, %rdi + call puts + jmp .L_exec_done +.L_exec_fail: + movq $.L_str_fail, %rdi + call puts +.L_exec_done: + popq %r13 + popq %r12 + leave + ret + .section .rodata +.L_debug_msg: + .string "debug %d\n" +.L_inp_0: + .string "" +.L_inp_1: + .string "x" + + .align 8 +inp: + .quad .L_inp_0 + .quad .L_inp_1 + + .align 8 +inplen: + .quad 2 + + .text + .globl main +main: + pushq %rbp + movq %rsp, %rbp + pushq %r12 + movq $0, %r12 +.L_again: + movq inplen(%rip), %rax + cmpq %r12, %rax + je .L_done + movq inp(,%r12,8), %rdi + call exec + incq %r12 + jmp .L_again +.L_done: + popq %r12 + mov $0, %rax + leave + ret +debug: + movl %edi, %esi + movq $0, %rax + movq $.L_debug_msg, %rdi + call printf + ret + diff --git a/test/trans.d/case/zlen1_c.rl b/test/trans.d/case/zlen1_c.rl new file mode 100644 index 00000000..fbeda2a0 --- /dev/null +++ b/test/trans.d/case/zlen1_c.rl @@ -0,0 +1,61 @@ +/* + * @LANG: c + * @GENERATED: true + */ + +#include +#include + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} + +void exec( char *data, int len ) +{ + char *p = data; + char *pe = data + len; + %% write exec; +} + +void finish( ) +{ + if ( cs >= zlen1_first_final ) + printf( "ACCEPT\n" ); + else + printf( "FAIL\n" ); +} + +char *inp[] = { +"", +"x", +}; + +int inplen = 2; + +int main( ) +{ + int i; + for ( i = 0; i < inplen; i++ ) { + init(); + exec( inp[i], strlen(inp[i]) ); + finish(); + } + return 0; +} + diff --git a/test/trans.d/case/zlen1_crack.rl b/test/trans.d/case/zlen1_crack.rl new file mode 100644 index 00000000..c4bfc983 --- /dev/null +++ b/test/trans.d/case/zlen1_crack.rl @@ -0,0 +1,46 @@ +// +// @LANG: crack +// @GENERATED: true +// + +import crack.io cout; +import crack.lang Buffer; + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; + +void m( String s ) +{ + byteptr data = s.buffer; + int p = 0; + int pe = s.size; + int cs; + String buffer; + + %% write init; + %% write exec; + + if ( cs >= zlen1_first_final ) { + cout `ACCEPT\n`; + } + else { + cout `FAIL\n`; + } +} + +void main() +{ + m( "" ); + m( "x" ); +} + +main(); diff --git a/test/trans.d/case/zlen1_cs.rl b/test/trans.d/case/zlen1_cs.rl new file mode 100644 index 00000000..fd5e7835 --- /dev/null +++ b/test/trans.d/case/zlen1_cs.rl @@ -0,0 +1,66 @@ +/* + * @LANG: csharp + * @GENERATED: true + */ + +using System; +// Disables lots of warnings that appear in the test suite +#pragma warning disable 0168, 0169, 0219, 0162, 0414 +namespace Test { +class Test +{ + + + +%%{ + machine zlen1; + main := zlen; +}%% + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char[] data, int len ) +{ + int p = 0; + int pe = len; + int eof = len; + string _s; + char [] buffer = new char [1024]; + int blen = 0; + %% write exec; +} + +void finish( ) +{ + if ( cs >= zlen1_first_final ) + Console.WriteLine( "ACCEPT" ); + else + Console.WriteLine( "FAIL" ); +} + +static readonly string[] inp = { +"", +"x", +}; + + +static readonly int inplen = 2; + +public static void Main (string[] args) +{ + Test machine = new Test(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].ToCharArray(), inp[i].Length ); + machine.finish(); + } +} +} +} diff --git a/test/trans.d/case/zlen1_d.rl b/test/trans.d/case/zlen1_d.rl new file mode 100644 index 00000000..61f43b11 --- /dev/null +++ b/test/trans.d/case/zlen1_d.rl @@ -0,0 +1,65 @@ +/* + * @LANG: d + * @GENERATED: true + */ + +import std.stdio; +import std.string; + +class zlen1 +{ + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; +int cs; +int blen; +char buffer[1024]; + +void init() +{ + %% write init; +} +void exec( const(char) data[] ) +{ + const(char) *p = data.ptr; + const(char) *pe = data.ptr + data.length; + char _s[]; + + %% write exec; +} + +void finish( ) +{ + if ( cs >= zlen1_first_final ) + writefln( "ACCEPT" ); + else + writefln( "FAIL" ); +} +static const char[][] inp = [ +"", +"x", +]; + +int inplen = 2; + +} +int main() +{ + zlen1 m = new zlen1(); + int i; + for ( i = 0; i < m.inplen; i++ ) { + m.init(); + m.exec( m.inp[i] ); + m.finish(); + } + return 0; +} + diff --git a/test/trans.d/case/zlen1_go.rl b/test/trans.d/case/zlen1_go.rl new file mode 100644 index 00000000..5c0446c8 --- /dev/null +++ b/test/trans.d/case/zlen1_go.rl @@ -0,0 +1,51 @@ +/* + * @LANG: go + * @GENERATED: true + */ + +package main +import "fmt" + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + +var cs int; +var blen int; +var buffer [1024] byte; + +%% write data; + +func prepare() { + %% write init; +} + +func exec(data string) { + var p int = 0 + var pe int = len(data) + %% write exec; +} +func finish() { + if cs >= zlen1_first_final { + fmt.Println("ACCEPT") + } else { + fmt.Println("FAIL") + } +} +var inp []string = []string { +"", +"x", +}; + +func main() { + for _, data := range inp { + prepare() + exec(data) + finish() + } +} diff --git a/test/trans.d/case/zlen1_java.rl b/test/trans.d/case/zlen1_java.rl new file mode 100644 index 00000000..71c483b6 --- /dev/null +++ b/test/trans.d/case/zlen1_java.rl @@ -0,0 +1,62 @@ +/* + * @LANG: java + * @GENERATED: true + */ + + +class zlen1_java +{ + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; +int cs; + +void init() +{ + %% write init; +} + +void exec( char data[], int len ) +{ + char buffer [] = new char[1024]; + int blen = 0; + int p = 0; + int pe = len; + + String _s; + %% write exec; +} + +void finish( ) +{ + if ( cs >= zlen1_first_final ) + System.out.println( "ACCEPT" ); + else + System.out.println( "FAIL" ); +} + +static final String inp[] = { +"", +"x", +}; + +static final int inplen = 2; + +public static void main (String[] args) +{ + zlen1_java machine = new zlen1_java(); + for ( int i = 0; i < inplen; i++ ) { + machine.init(); + machine.exec( inp[i].toCharArray(), inp[i].length() ); + machine.finish(); + } +} +} diff --git a/test/trans.d/case/zlen1_julia.rl b/test/trans.d/case/zlen1_julia.rl new file mode 100644 index 00000000..c216470d --- /dev/null +++ b/test/trans.d/case/zlen1_julia.rl @@ -0,0 +1,36 @@ +// +// @LANG: julia +// @GENERATED: true +// + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; + +function m( data::AbstractString ) + p = 0 + pe = length(data) + eof = length(data) + cs = 0 + buffer = "" + + %% write init; + %% write exec; + + if ( cs >= zlen1_first_final ) + println( "ACCEPT" ); + else + println( "FAIL" ); + end +end + + m( "" ); + m( "x" ); diff --git a/test/trans.d/case/zlen1_ocaml.rl b/test/trans.d/case/zlen1_ocaml.rl new file mode 100644 index 00000000..814d8657 --- /dev/null +++ b/test/trans.d/case/zlen1_ocaml.rl @@ -0,0 +1,38 @@ +(* + * @LANG: ocaml + * @GENERATED: true + *) + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + + +%% write data; + +let exec data = + let buffer = String.create(1024) in + let blen :int ref = ref 0 in + let cs = ref 0 in + let p = ref 0 in + let pe = ref (String.length data) in + %% write init; + %% write exec; + if !cs >= zlen1_first_final then + print_string "ACCEPT\n" + else + print_string "FAIL\n" +;; + +let () = + exec ""; + exec "x"; + () +;; + diff --git a/test/trans.d/case/zlen1_ruby.rl b/test/trans.d/case/zlen1_ruby.rl new file mode 100644 index 00000000..8f3d75ad --- /dev/null +++ b/test/trans.d/case/zlen1_ruby.rl @@ -0,0 +1,44 @@ +# +# @LANG: ruby +# @GENERATED: true +# + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; + +def run_machine( data ) + p = 0 + pe = data.length + eof = data.length + cs = 0; + _m = + _a = + buffer = Array.new + blen = 0 + %% write init; + %% write exec; + if cs >= zlen1_first_final + puts "ACCEPT" + else + puts "FAIL" + end +end + +inp = [ +"", +"x", +] + +inplen = 2 + +inp.each { |str| run_machine(str) } + diff --git a/test/trans.d/case/zlen1_rust.rl b/test/trans.d/case/zlen1_rust.rl new file mode 100644 index 00000000..b47751ca --- /dev/null +++ b/test/trans.d/case/zlen1_rust.rl @@ -0,0 +1,43 @@ +// +// @LANG: rust +// @GENERATED: true +// + + + + +%%{ + machine zlen1; + main := zlen; +}%% + + + +%% write data; + +unsafe fn m( s: String ) +{ + let data: &[u8] = s.as_bytes(); + let mut p:i32 = 0; + let mut pe:i32 = s.len() as i32; + let mut eof:i32 = s.len() as i32; + let mut cs: i32 = 0; + let mut buffer = String::new(); + + %% write init; + %% write exec; + + if ( cs >= zlen1_first_final ) { + println!( "ACCEPT" ); + } + else { + println!( "FAIL" ); + } +} + +fn main() +{ + unsafe { m( "".to_string() ); } + unsafe { m( "x".to_string() ); } +} + diff --git a/test/trans.d/gentests b/test/trans.d/gentests new file mode 100755 index 00000000..130c4b23 --- /dev/null +++ b/test/trans.d/gentests @@ -0,0 +1,45 @@ +#!/bin/bash +# + +. ../colm.sh + +langs='asm crack c cs d go java julia ocaml' + +mkdir -p working + +echo working/* | xargs rm -f + +[ $# = 0 ] && set -- `find case -type f -and -not -name '*_*' | sort` + +for fn; do + + prohibit_languages=`sed '/@PROHIBIT_LANGUAGES:/s/^.*: *//p;d' $fn` + + for l in $langs; do + + echo "$prohibit_languages" | grep -q "\<$l\>" && continue; + + out=${fn%.rl}_$l.out + out=working/${out#case/} + + class=${fn%.rl} + class=${class#case/}_$l + + exp=${fn%.rl}_$l.rl + + diff=${fn%.rl}_$l.out + diff=working/${diff#case/} + + sh=${fn%.rl}_$l.sh + sh=working/${sh#case/} + + rm -f $sh + + echo echo testing $l $fn >> $sh + echo ./trans $l $out $fn $class >> $sh + echo diff $exp $out '>' $diff >> $sh + + echo $sh + done +done + diff --git a/test/trans.d/main.c b/test/trans.d/main.c new file mode 100644 index 00000000..7d3b0824 --- /dev/null +++ b/test/trans.d/main.c @@ -0,0 +1,16 @@ +#include + +extern struct colm_sections trans_object; + +int main( int argc, const char **argv ) +{ + struct colm_program *prg; + int exit_status; + + prg = colm_new_program( &trans_object ); + colm_set_debug( prg, 0 ); + colm_run_program( prg, argc, argv ); + exit_status = colm_delete_program( prg ); + return exit_status; +} + diff --git a/test/trans.d/ragel-c.lm b/test/trans.d/ragel-c.lm new file mode 100644 index 00000000..ccc2dc93 --- /dev/null +++ b/test/trans.d/ragel-c.lm @@ -0,0 +1,175 @@ +namespace c_inline + lex + literal `fpc `fc `fcurs `ftargs + `fentry `fhold `fexec `fgoto `fnext + `fcall `fret `fbreak `fncall `fnret `fnbreak + + token ident /ident/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / c_comment | cpp_comment / + + token string + / s_literal | d_literal / + + token whitespace + / ( [ \t] | NL )+ / + + literal + `{ `} `:: `* `, `( `) `; + + token var_ref + / "$" [a-zA-Z_][a-zA-Z_0-9]* / + { + if GblActionParams + { + input->push( make_token( + typeid, input->pull( match_length ) ) ) + } + else + { + # Just pull one char. Don't consume the word because it may + # be a keyword. + input->push( make_token( + typeid, input->pull( 1 ) ) ) + } + } + + token c_any + / any / + end + + def inline_expr + [expr_item_list] :List + + def expr_item_list + [expr_item_list expr_item] :Rec + | [] :Empty + + def expr_item + [expr_any] :ExprAny + | [expr_symbol] :ExprSymbol + | [expr_interpret] :ExprInterpret + + def expr_any + [whitespace] :WS + | [comment] :Comment + | [string] :String + | [number] :Number + | [hex_number] :Hex + | [ident] :Ident + | [c_any] :Any + + def expr_symbol + [`,] :Comma | [`(] :Open | [`)] :Close | [`*] :Star | [`::] :DoubleColon + + def expr_interpret + [`fpc] :Fpc + | [`fc] :Fc + | [`fcurs] :Fcurs + | [`ftargs] :Ftargs + | [`fentry `( state_ref srlex::`)] :Fentry + | [var_ref] :VarRef + + def state_ref + [opt_name_sep state_ref_names] :Ref + + def opt_name_sep + [srlex::`::] :ColonColon + | [] :Empty + + # List of names separated by :: + def state_ref_names + [state_ref_names srlex::`:: srlex::word] :Rec + | [srlex::word] :Base + + def inline_block + [block_item_list] :List + + def block_item_list + [block_item block_item_list] :Rec + | [] :Base + + def block_item + [expr_any] :ExprAny + | [block_symbol] :BlockSymbol + | [block_interpret] :BlockInterpret + | [`{ inline_block `}] :RecBlock + + def block_symbol + [`,] :B1 | [`;] :B2 | [`(] :B3 | [`)] :B4 | [`*] :B5 | [`::] :B6 + + def block_interpret + [expr_interpret] :ExprInterpret + | [`fhold whitespace? `;] :Fhold + | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr + | [`fnext whitespace? `* inline_expr `;] :FnextExpr + | [`fcall whitespace? `* inline_expr `;] :FcallExpr + | [`fncall whitespace? `* inline_expr `;] :FncallExpr + | [`fexec inline_expr `;] :Fexec + | [`fgoto state_ref srlex::`;] :FgotoSr + | [`fnext state_ref srlex::`;] :FnextSr + | [`fcall state_ref srlex::`;] :FcallSr + | [`fncall state_ref srlex::`;] :FncallSr + | [`fret `;] :Fret + | [`fnret `;] :Fnret + | [`fbreak `;] :Fbreak + | [`fnbreak `;] :Fnbreak +end + + +namespace c_host + lex + literal `%%{ + + token slr / '%%' [^{] [^\n]* '\n' / + { + # Translates single line to multi-line + input->pull( 2 ) + R: str = input->pull( match_length - 3 ) + input->push( "\n}%%" ) + input->push( R ) + input->push( "%%{" ) + } + + rl NL / '\n' / + + rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + + rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + + token ident /ident "'"?/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / c_comment | cpp_comment / + + token string + / s_literal | d_literal / + + token whitespace + / ( [ \t] | NL )+ / + + token c_any / any / + end + + def tok + [ident] :Ident + | [number] :Number + | [hex_number] :HexNumber + | [comment] :Comment + | [string] :String + | [whitespace] :Whitespace + | [c_any] :Any + + def section + [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine + | [tok] :Tok +end + + diff --git a/test/trans.d/ragel-crack.lm b/test/trans.d/ragel-crack.lm new file mode 100644 index 00000000..b6480012 --- /dev/null +++ b/test/trans.d/ragel-crack.lm @@ -0,0 +1,150 @@ +namespace crack_inline + lex + literal `fpc `fc `fcurs `ftargs + `fentry `fhold `fexec `fgoto `fnext + `fcall `fret `fbreak `fncall `fnret `fnbreak + + token ident /ident/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / c_comment | cpp_comment / + + token string + / s_literal | d_literal / + + token whitespace + / ( [ \t] | NL )+ / + + literal + `{ `} `:: `* `, `( `) `; + + token c_any / any / + end + + def inline_expr + [expr_item*] + + def expr_item + [expr_any] :ExprAny + | [expr_symbol] :ExprSymbol + | [expr_interpret] :ExprInterpret + + def expr_any + [whitespace] + | [comment] + | [string] + | [number] + | [hex_number] + | [ident] + | [c_any] + + def expr_symbol + [`,] | [`(] | [`)] | [`*] | [`::] + + def expr_interpret + [`fpc] :Fpc + | [`fc] :Fc + | [`fcurs] :Fcurs + | [`ftargs] :Ftargs + | [`fentry `( state_ref srlex::`)] :Fentry + + def state_ref + [opt_name_sep state_ref_names] + + def opt_name_sep + [srlex::`::] :ColonColon + | [] :Empty + + # List of names separated by :: + def state_ref_names + [state_ref_names srlex::`:: srlex::word] :Rec + | [srlex::word] :Base + + def inline_block + [block_item*] + + def block_item + [expr_any] :ExprAny + | [block_symbol] :BlockSymbol + | [block_interpret] :BlockInterpret + | [`{ inline_block `}] :RecBlock + + def block_symbol + [`,] | [`;] | [`(] | [`)] | [`*] | [`::] + + def block_interpret + [expr_interpret] :ExprInterpret + | [`fhold whitespace? `;] :Fhold + | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr + | [`fnext whitespace? `* inline_expr `;] :FnextExpr + | [`fcall whitespace? `* inline_expr `;] :FcallExpr + | [`fncall whitespace? `* inline_expr `;] :FncallExpr + | [`fexec inline_expr `;] :Fexec + | [`fgoto state_ref srlex::`;] :FgotoSr + | [`fnext state_ref srlex::`;] :FnextSr + | [`fcall state_ref srlex::`;] :FcallSr + | [`fncall state_ref srlex::`;] :FncallSr + | [`fret `;] :Fret + | [`fnret `;] :Fnret + | [`fbreak `;] :Fbreak + | [`fnbreak `;] :Fnbreak +end + + +namespace crack_host + lex + literal `%%{ + + token slr /'%%' [^{] [^\n]* '\n'/ + { + input->pull( 2 ) + R: str = input->pull( match_length - 3 ) + input->push( "\n}%%" ) + input->push( R ) + input->push( "%%{" ) + } + + rl NL / '\n' / + + rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + + rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + + rl bt_literal + / '`' ([^`\\] | NL | '\\' (any | NL))* '`' / + + token ident /ident "'"?/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + /c_comment | cpp_comment/ + + token string + / s_literal | d_literal | bt_literal / + + token whitespace + / ( [ \t] | NL )+ / + + token c_any / any / + end + + def tok + [ident] + | [number] + | [hex_number] + | [comment] + | [string] + | [whitespace] + | [c_any] + + def section + [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine + | [tok] :Tok +end + + diff --git a/test/trans.d/ragel-ocaml.lm b/test/trans.d/ragel-ocaml.lm new file mode 100644 index 00000000..2b89535b --- /dev/null +++ b/test/trans.d/ragel-ocaml.lm @@ -0,0 +1,147 @@ +namespace ocaml_inline + lex + literal `fpc `fc `fcurs `ftargs + `fentry `fhold `fexec `fgoto `fnext + `fcall `fret `fbreak `fncall `fnret `fnbreak + + token ident /ident/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / c_comment | cpp_comment / + + token string + / s_literal | d_literal / + + token whitespace + / ( [ \t] | NL )+ / + + literal + `{ `} `:: `* `, `( `) `; + + token c_any / any / + end + + def inline_expr + [expr_item*] + + def expr_item + [expr_any] :ExprAny + | [expr_symbol] :ExprSymbol + | [expr_interpret] :ExprInterpret + + def expr_any + [whitespace] + | [comment] + | [string] + | [number] + | [hex_number] + | [ident] + | [c_any] + + def expr_symbol + [`,] | [`(] | [`)] | [`*] | [`::] + + def expr_interpret + [`fpc] :Fpc + | [`fc] :Fc + | [`fcurs] :Fcurs + | [`ftargs] :Ftargs + | [`fentry `( state_ref srlex::`)] :Fentry + + def state_ref + [opt_name_sep state_ref_names] + + def opt_name_sep + [srlex::`::] :ColonColon + | [] :Empty + + # List of names separated by :: + def state_ref_names + [state_ref_names srlex::`:: srlex::word] :Rec + | [srlex::word] :Base + + def inline_block + [block_item*] + + def block_item + [expr_any] :ExprAny + | [block_symbol] :BlockSymbol + | [block_interpret] :BlockInterpret + | [`{ inline_block `}] :RecBlock + + def block_symbol + [`,] | [`;] | [`(] | [`)] | [`*] | [`::] + + def block_interpret + [expr_interpret] :ExprInterpret + | [`fhold whitespace? `;] :Fhold + | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr + | [`fnext whitespace? `* inline_expr `;] :FnextExpr + | [`fcall whitespace? `* inline_expr `;] :FcallExpr + | [`fncall whitespace? `* inline_expr `;] :FncallExpr + | [`fexec inline_expr `;] :Fexec + | [`fgoto state_ref srlex::`;] :FgotoSr + | [`fnext state_ref srlex::`;] :FnextSr + | [`fcall state_ref srlex::`;] :FcallSr + | [`fncall state_ref srlex::`;] :FncallSr + | [`fret `;] :Fret + | [`fnret `;] :Fnret + | [`fbreak `;] :Fbreak + | [`fnbreak `;] :Fnbreak +end + + +namespace ocaml_host + lex + literal `%%{ + + token slr /'%%' [^{] [^\n]* '\n'/ + { + input->pull( 2 ) + R: str = input->pull( match_length - 3 ) + input->push( "\n}%%" ) + input->push( R ) + input->push( "%%{" ) + } + + rl NL / '\n' / + + rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + + rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + + token ident /ident "'"?/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + /c_comment | cpp_comment/ + + token string + / s_literal | d_literal / + + token whitespace + / ( [ \t] | NL )+ / + + token ocaml_any / any / + end + + def tok + [ident] + | [number] + | [hex_number] + | [comment] + | [string] + | [whitespace] + | [ocaml_any] + + def section + [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine + | [tok] :Tok +end + + diff --git a/test/trans.d/ragel-ruby.lm b/test/trans.d/ragel-ruby.lm new file mode 100644 index 00000000..29e36887 --- /dev/null +++ b/test/trans.d/ragel-ruby.lm @@ -0,0 +1,146 @@ +namespace ruby_inline + lex + literal `fpc `fc `fcurs `ftargs + `fentry `fhold `fexec `fgoto `fnext + `fcall `fret `fbreak `fncall `fnret `fnbreak + + token ident /ident/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / ruby_comment / + + token string + / s_literal | d_literal | host_re_literal / + + token whitespace + / ( [ \t] | NL )+ / + + literal + `{ `} `:: `* `, `( `) `; + + token ruby_any / any / + end + + def inline_expr + [expr_item*] + + def expr_item + [expr_any] :ExprAny + | [expr_symbol] :ExprSymbol + | [expr_interpret] :ExprInterpret + + def expr_any + [whitespace] + | [comment] + | [string] + | [number] + | [hex_number] + | [ident] + | [ruby_any] + + def expr_symbol + [`,] | [`(] | [`)] | [`*] | [`::] + + def expr_interpret + [`fpc] :Fpc + | [`fc] :Fc + | [`fcurs] :Fcurs + | [`ftargs] :Ftargs + | [`fentry `( state_ref srlex::`)] :Fentry + + def state_ref + [opt_name_sep state_ref_names] + + def opt_name_sep + [srlex::`::] :ColonColon + | [] :Empty + + # List of names separated by :: + def state_ref_names + [state_ref_names srlex::`:: srlex::word] :Rec + | [srlex::word] :Base + + def inline_block + [block_item*] + + def block_item + [expr_any] :ExprAny + | [block_symbol] :BlockSymbol + | [block_interpret] :BlockInterpret + | [`{ inline_block `}] :RecBlock + + def block_symbol + [`,] | [`;] | [`(] | [`)] | [`*] | [`::] + + def block_interpret + [expr_interpret] :ExprInterpret + | [`fhold whitespace? `;] :Fhold + | [`fgoto whitespace? `* inline_expr `;] :FgotoExpr + | [`fnext whitespace? `* inline_expr `;] :FnextExpr + | [`fcall whitespace? `* inline_expr `;] :FcallExpr + | [`fncall whitespace? `* inline_expr `;] :FncallExpr + | [`fexec inline_expr `;] :Fexec + | [`fgoto state_ref srlex::`;] :FgotoSr + | [`fnext state_ref srlex::`;] :FnextSr + | [`fcall state_ref srlex::`;] :FcallSr + | [`fncall state_ref srlex::`;] :FncallSr + | [`fret `;] :Fret + | [`fnret `;] :Fnret + | [`fbreak `;] :Fbreak + | [`fnbreak `;] :Fnbreak +end + +namespace ruby_host + lex + literal `%%{ + + token slr /'%%' [^{] [^\n]* '\n'/ + { + input->pull( 2 ) + R: str = input->pull( match_length - 3 ) + input->push( "\n}%%" ) + input->push( R ) + input->push( "%%{" ) + } + + rl NL / '\n' / + + rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + + rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + + token ident /ident/ + token number /digit+/ + token hex_number /'0x' [0-9a-fA-F]+/ + + token comment + / ruby_comment / + + token string + / s_literal | d_literal | host_re_literal / + + token whitespace + / ( [ \t] | NL )+ / + + token ruby_any / any / + end + + def tok + [ident] + | [number] + | [hex_number] + | [comment] + | [string] + | [whitespace] + | [ruby_any] + + def section + [`%%{ ragel::ragel_start ragel::`}%%] :MultiLine + | [tok] :Tok +end + + diff --git a/test/trans.d/ragel.lm b/test/trans.d/ragel.lm new file mode 100644 index 00000000..64d5bb6a --- /dev/null +++ b/test/trans.d/ragel.lm @@ -0,0 +1,559 @@ +global GblActionParams: bool = false +global GblSectionPass: bool = false + +bool action_params_find( Machine: str, Action: str ) += cc_action_params_find + +bool action_params_insert( Machine: str, Action: str ) += cc_action_params_insert + +rl ident + /( alpha | '_' ) ( alpha | digit | '_' )*/ + +rl number + / digit+ / + +rl hex_number + / '0x' [0-9a-fA-F]+ / + +rl hex_char + / '0x' [0-9a-fA-F]{2} / + +## Optimization for hex chars that appear near to each other. Converts the +## string of 2-digit hex chars into a single string. The parse tree walker +## concatenates the chars. +#rl hex_string / +# hex_char +# ( +# ( +# [\t\n ]+ | +# [\t\n ]* '.' [\t\n ]* +# ) +# hex_char +# )+ +#/ + +rl NL / '\n' / + +rl c_comment + / '/*' ( any | NL )* :>> '*/' / + +rl cpp_comment + / '//' [^\n]* NL / + +rl ruby_comment + / '#' [^\n]* NL / + +rl s_literal + / "'" ([^'\\\n] | '\\' (any | NL))* "'" / + +rl d_literal + / '"' ([^"\\] | NL | '\\' (any | NL))* '"' / + +rl host_re_literal + / '/' ([^/\\] | NL | '\\' (any | NL))* '/' / + +namespace srlex + lex + ignore /[\t\n ]+/ + literal `:: `; `) + token word /[a-zA-Z_][a-zA-Z0-9_]*/ + end +end + +struct machine + Name: str + ActionParams: map +end + +global MachineMap: map = new map() +global CurMachine: machine + +global Lang: str + +lex + token select /''/ + { + if Lang == "ruby" + input->push( make_token( typeid, '' ) ) + elsif Lang == "ocaml" + input->push( make_token( typeid, '' ) ) + elsif Lang == "crack" + input->push( make_token( typeid, '' ) ) + else + input->push( make_token( typeid, '' ) ) + } + + token c_select // + token ruby_select // + token ocaml_select // + token crack_select // +end + + +namespace ragel + lex + literal `}%% -ni + + ignore /[\t\n ]+/ + ignore /'#' any* :> '\n'/ + + literal `^ `| `- `, `: `! `? `. + literal `( `) `{ -ni ni- `} `* `& `+ + + literal `-- `:> `:>> `<: `-> `** + + literal `|* `*| `=> + + literal `@ `> `< `% `$ + literal `from `to `eof `lerr `err + literal `when `inwhen `outwhen `>? `$? `%? + + literal `:= `|= `= `; `.. `../i `:: + + literal `>~ `$~ `%~ `<~ `@~ `<>~ + literal `>* `$* `%* `<* `@* `<>* + literal `>/ `$/ `%/ `/ + literal `>! `$! `%! `! + literal `>^ `$^ `%^ `<^ `@^ `<>^ + literal `<> + + literal `machine `action `variable `alphtype + `access `write `getkey `export `import + `include `prepush `postpop `nfaprepush `nfapostpop + + literal `:nfa `:cond `:condplus `:condstar `): + + token string / + '"' ( [^"\\] | '\\' any )* '"' 'i'? | + "'" ( [^'\\] | '\\' any )* "'" 'i'? + / + + # token hex_string / hex_string / + + token lex_regex_open /'/'/ -ni + token lex_sqopen_pos /'['/ -ni + token lex_sqopen_neg /'[^'/ -ni + + token word / [a-zA-Z_][a-zA-Z0-9_]* / + token uint / number / + token hex / hex_number / + end + + lex + token re_dot / '.' / + token re_star / '*' / + token re_char / ^( '\\' | '.' | '*' | '[' | '/' ) | '\\' . any / + token re_close / '/' 'i'? / + token re_sqopen_pos /'['/ + token re_sqopen_neg /'[^'/ + end + + lex + token re_or_dash / '-' / + token re_or_char / ^( '\\' | '-' | ']' ) | '\\' . any / + token re_or_sqclose / ']' / + end + + # Not cannot start with '{', terminated by ';', rewritten into { inline_expr } + token _inline_expr_reparse + /[^{;] [^;]* ';'/ { + R: str = input->pull( match_length - 1 ) + input->pull( 1 ) + input->push( "}" ) + input->push( R ) + input->push( "{" ) + } + + token variable_name /ident/ + + def inline_expr_reparse + [_inline_expr_reparse] :Reparse + | [action_expr] :ActionExpr + + def join + [join `, expression] :Rec + | [expression] :Base + + def expression + [expr_left expression_op_list] :Expression + + def expression_op_list + [expression_op expression_op_list] :Op + | [] :Empty + + def expression_op + [`| term] :Or + | [`& term] :And + | [`- term] :Sub + | [`-- term] :Ssub + + def expr_left + [term] :Term + + def term + [term_left term_op_list_short] :Term + + def term_left + [factor_label] :FactorLabel + + # This list is done manually to get shortest match. + def term_op_list_short + [] :Empty + | [term_op term_op_list_short] :Terms + + def term_op + [factor_label] :None + | [`. factor_label] :Dot + | [`:> factor_label] :ColonLt + | [`:>> factor_label] :ColonLtLt + | [`<: factor_label] :GtColon + + def factor_label + [word `: factor_label] :Label + | [factor_ep] :Ep + + def factor_ep + [factor_aug `-> epsilon_target] :Epsilon + | [factor_aug] :Base + + def epsilon_target + [epsilon_target `:: word] :Rec + | [word] :Base + + def action_expr + [`{ c_select CInlineExpr: c_inline::inline_expr c_inline::`}] :C + | [`{ ruby_select RubyInlineExpr: ruby_inline::inline_expr ruby_inline::`}] + | [`{ ocaml_select OCamlInlineExpr: ocaml_inline::inline_expr ocaml_inline::`}] + | [`{ crack_select CrackInlineExpr: crack_inline::inline_expr crack_inline::`}] + + def action_block + [`{ c_select CInlineBlock: c_inline::inline_block c_inline::`}] :C + | [`{ ruby_select RubyInlineBlock: ruby_inline::inline_block ruby_inline::`}] + | [`{ ocaml_select OCamlInlineBlock: ocaml_inline::inline_block ocaml_inline::`}] + | [`{ crack_select CrackInlineBlock: crack_inline::inline_block crack_inline::`}] + + def action_arg_list + [action_arg_list `, action_ref] :Rec + | [action_ref] :Base + + def opt_action_arg_list + [action_arg_list] :List + | [] :Empty + + def named_action_ref + [word] :Plain + { + if ! GblSectionPass { + if action_params_find( CurMachine->Name, $lhs.word ) + reject + } + } + | [word `( opt_action_arg_list `)] :Args + { + if ! GblSectionPass { + if ! action_params_find( CurMachine->Name, $lhs.word ) + reject + } + } + + def action_ref + [named_action_ref] :NamedRef + | [`( named_action_ref `)] :ParenNamed + | [action_block] :Block + + def priority_name + [word] :Word + + def error_name + [word] :Word + + def priority_aug + [uint] :NoSign + | [`+ uint] :Plus + | [`- uint] :Minus + + def aug_base + [`@] :Finish | [`>] :Enter | [`%] :Leave | [`$] :All + + def aug_cond + [`>?] :Start1 | [`$?] :All1 | [`%?] :Leave1 + | [`> `when] :Start2 | [`$ `when] :All2 | [`% `when] :Leave2 + | [`inwhen] :Start3 | [`when] :All3 | [`outwhen] :Leave3 + + def aug_to_state + [`>~] :Start1 | [`<~] :NotStart1 | [`$~] :All1 + | [`%~] :Final1 | [`@~] :NotFinal1 | [`<>~] :Middle1 + | [`> `to] :Start2 | [`< `to] :NotStart2 | [`$ `to] :All2 + | [`% `to] :Final2 | [`@ `to] :NotFinal2 | [`<> `to] :Middle2 + + def aug_from_state + [`>*] :Start1 | [`<*] :NotStart1 | [`$*] :All1 + | [`%*] :Final1 | [`@*] :NotFinal1 | [`<>*] :Middle1 + | [`> `from] :Start2 | [`< `from] :NotStart2 | [`$ `from] :All2 + | [`% `from] :Final2 | [`@ `from] :NotFinal2 | [`<> `from] :Middle2 + + def aug_eof + [`>/] :Start1 | [`/] :Middle1 + | [`> `eof] :Start2 | [`< `eof] :NotStart2 | [`$ `eof] :All2 + | [`% `eof] :Final2 | [`@ `eof] :NotFinal2 | [`<> `eof] :Middle2 + + def aug_gbl_error + [`>!] :Start1 | [`!] :Middle1 + | [`> `err] :Start2 | [`< `err] :NotStart2 | [`$ `err] :All2 + | [`% `err] :Final2 | [`@ `err] :NotFinal2 | [`<> `err] :Middle2 + + def aug_local_error + [`>^] :Start1 | [`<^] :NotStart1 | [`$^] :All1 + | [`%^] :Final1 | [`@^] :NotFinal1 | [`<>^] :Middle1 + | [`> `lerr] :Start2 | [`< `lerr] :NotStart2 | [`$ `lerr] :All2 + | [`% `lerr] :Final2 | [`@ `lerr] :NotFinal2 | [`<> `lerr] :Middle2 + + def factor_aug + [factor_aug aug_base action_ref] :ActionRef + | [factor_aug aug_base priority_aug] :PriorEmbed + | [factor_aug aug_base `( priority_name `, priority_aug `)] :NamedPriorEmbed + | [factor_aug aug_cond action_ref] :CondEmbed + | [factor_aug aug_cond `! action_ref] :NegCondEmbed + | [factor_aug aug_to_state action_ref] :ToStateAction + | [factor_aug aug_from_state action_ref] :FromStateAction + | [factor_aug aug_eof action_ref] :EofAction + | [factor_aug aug_gbl_error action_ref] :GblErrorAction + | [factor_aug aug_local_error action_ref] :LocalErrorDef + | [factor_aug aug_local_error `( error_name `, action_ref `)] :LocalErrorName + | [factor_rep] :Base + + def factor_rep + [factor_neg factor_rep_op_list] :Op + + def factor_rep_op_list + [factor_rep_op factor_rep_op_list] :Rec + | [] :Base + + def factor_rep_op + [`*] :Star + | [`**] :StarStar + | [`?] :Optional + | [`+] :Plus + | [`{ factor_rep_num `}] :ExactRep + | [`{ `, factor_rep_num `}] :MaxRep + | [`{ factor_rep_num `, `}] :MinRep + | [`{ LowRep: factor_rep_num `, HighRep: factor_rep_num `}] :RangeRep + + def factor_rep_num + [uint] :RepNum + + def factor_neg + [`! factor_neg] :Bang + | [`^ factor_neg] :Caret + | [factor] :Base + + def opt_max_arg + [`, action_ref] :Action + | [] :Empty + + def nfastar + [`:nfa] + + def colon_cond + [`:cond] :Cond + | [`:condstar] :CondStar + | [`:condplus] :CondPlus + + def factor + [alphabet_num] :AlphabetNum + | [word] :Word + | [string] :String + #| [hex_string] :HexString + | [lex_sqopen_pos reg_or_data re_or_sqclose] :PosOrBlock + | [lex_sqopen_neg reg_or_data re_or_sqclose] :NegOrBlock + | [lex_regex_open regex re_close] :Regex + | [RL1: range_lit `.. RL2: range_lit] :Range + | [RL1: range_lit `../i RL2: range_lit] :RangeIndep + | [nfastar `( expression `, + Push: action_ref `, Pop: action_ref `, Init: action_ref `, Stay: action_ref `, + Repeat: action_ref `, Exit: action_ref `):] :Nfa + | [colon_cond `( expression `, + Init: action_ref `, Inc: action_ref `, Min: action_ref OptMax: opt_max_arg `):] :Cond + | [`( join `)] :Join + + def regex + [reg_item_rep_list] :List + + def reg_item_rep_list + [reg_item_rep_list reg_item_rep] :Rec + | [] :Base + + def reg_item_rep + [reg_item re_star] :Star + | [reg_item] :Base + + def reg_item + [re_sqopen_pos reg_or_data re_or_sqclose] :PosOrBlock + | [re_sqopen_neg reg_or_data re_or_sqclose] :NegOrBlock + | [re_dot] :Dot + | [re_char] :Char + + def reg_or_data + [reg_or_data reg_or_char] :Data + | [] :Base + + def reg_or_char + [re_or_char] :Char + | [Low: re_or_char re_or_dash High: re_or_char] :Range + + def range_lit + [string] :String + | [alphabet_num] :AN + + def alphabet_num + [uint] :Uint + | [`- uint] :Neg + | [hex] :Hex + + def lm_act + [`=> action_ref] :ActionRef + | [action_block] :ActionBlock + + def opt_lm_act + [lm_act] :Act + | [] :Empty + + def lm_stmt + [join opt_lm_act `;] :LmStmt commit + | [assignment] :Assignment + | [action_spec] :ActionSpec + + def lm_stmt_list + [lm_stmt_list lm_stmt] :Rec + | [lm_stmt] :Base + + def lm + [join] :Join + | [`|* lm_stmt_list `*|] :Lm + + # + # Actions + # + def action_param + [word] :Word + + def action_param_list + [action_param_list `, action_param] :Rec + | [action_param] :Base + + def opt_action_param_list + [action_param_list] :List + | [] :Empty + + def action_params + [`( opt_action_param_list `)] :List + { + GblActionParams = true + } + + def action_spec + [`action word action_params action_block] :ActionSpecParams commit + { + if ! GblSectionPass { + # Track that this action has params so we can parse appropriately + # when reducing. + # CurMachine->ActionParams->insert( $lhs.word, $lhs.word ) + action_params_insert( CurMachine->Name, $lhs.word ) + } + + # Reset after parsing the block. + GblActionParams = false + } + | [`action word action_block] :ActionSpec commit + { + GblActionParams = false + } + + def def_name + [word] :Word + + # + # Machine Instantiations. + # + def assignment + [opt_export def_name `= join `;] :Assignment commit + + def instantiation + [opt_export def_name `:= lm `;] :Instantiation commit + + def nfa_expr + [nfa_expr `| term] :Union + | [term] :Base + + def nfa_round_spec + [Depth: uint `, Group: uint] :Spec + + def nfa_round_list + [nfa_round_list `, nfa_round_spec] :Recurse + | [nfa_round_spec] :Base + + def nfa_rounds + [`( nfa_round_list `)] :Rounds + + def nfa_union + [def_name `|= nfa_rounds nfa_expr `;] :NfaUnion commit + + def alphtype_type + [W1: word] :One + | [W1: word W2: word] :Two + + def include_spec + [word] :Machine + | [string] :File + | [word string] :MachineFile + + def opt_export + [`export] :Export + | [] :Base + + def write_arg + [word] :Word + + def machine_name + [`machine word `;] :MachineName + { + Machine: machine = MachineMap->find( $lhs.word ) + + if !Machine + { + Machine = new machine() + Machine->Name = $lhs.word + Machine->ActionParams = new map() + MachineMap->insert( Machine->Name, Machine ) + } + + CurMachine = Machine + } + + def statement + [assignment] :Assignment + | [instantiation] :Instantiation + | [nfa_union] :NfaUnion + | [action_spec] :ActionSpec + | [`prepush action_block] :PrePush commit + | [`postpop action_block] :PostPop commit + | [`variable variable_name inline_expr_reparse] :Variable commit + | [`alphtype alphtype_type `;] :AlphType commit + | [`access inline_expr_reparse] :Access commit + | [`write Cmd: word ArgList: write_arg* `;] :Write commit + | [`getkey inline_expr_reparse] :GetKey commit + | [`import string `;] :Import commit + | [`include include_spec `;] :Include commit + | [`nfaprepush action_block] :NfaPrePush commit + | [`nfapostpop action_block] :NfaPostPop commit + + def opt_machine_name + [machine_name] :MachineName + | [] :Empty + + def ragel_start + [opt_machine_name statement*] +end diff --git a/test/trans.d/trans-asm.lm b/test/trans.d/trans-asm.lm new file mode 100644 index 00000000..1adcb6af --- /dev/null +++ b/test/trans.d/trans-asm.lm @@ -0,0 +1,601 @@ +global Label: int = 1 + +int rw_asm_factor( Factor: indep::factor ) +{ + switch Factor + #if match Factor [`first_token_char] + #{ + # send Out "ts\[0\]" + #} + #else if match Factor [tk_ident `[ expr `]] + #{ + # send Out + # "[$Factor.tk_ident]\[ [rw_c_expr(Factor.expr)] \] + #} + #else if match Factor [tk_ident `( expr `)] + #{ + # send Out + # "[$Factor.tk_ident]( [rw_c_expr(Factor.expr)] ) + #} + case [`< type `> `( expr `)] { + rw_asm_expr( Factor.expr ) + } + case [`( expr `)] { + rw_asm_expr( Factor.expr ) + } + case ['true'] { + send Out + " movq $1, %rax + " pushq %rax + } + case ['false'] { + send Out + " movq $0, %rax + " pushq %rax + } + case [`fentry `( E: expr `)] { + send Out + " movq $fentry([E]), %rax + " pushq %rax + } + case [`fc] { + send Out + " movsbq (%r12), %rax + " pushq %rax + } + case [`fcurs] { + send Out + " fcurs; + " pushq %rax + } + case [`ftargs] { + send Out + " ftargs; + " pushq %rax + } + case ["p"] { + send Out + " pushq %r12 + } + case ["te"] { + send Out + " movq -24(%rbp), %rax + " pushq %rax + } + case [Ident: tk_ident] { + send Out + " movq [Ident](%rip), %rax + " pushq %rax + } + case [Number: tk_number] { + send Out + " movq $[Number], %rax + " pushq %rax + } + case [`- Number: tk_number] { + send Out + " movq $-[Number], %rax + " pushq %rax + + } + case "'0'" { + send Out + " movq $48, %rax + " pushq %rax + } + case "'a'" { + send Out + " movq $97, %rax + " pushq %rax + } + case [String: string] { + send Out + " .section .rodata + "[Label]: + " .string [String] + " .text + " movq $[Label]b, %rax + " pushq %rax + Label = Label + 1 + } + case [`buffer] { + send Out + " movq $buf, %rax + " pushq %rax + } + case [`blen] { + send Out + " movq bpos(%rip), %rax + " pushq %rax + } + case [`first_token_char] + { + # Tokstart: -16 + send Out + " movq -16(%rbp), %rax + " movsbq (%rax), %rcx + " pushq %rcx + } + default { + send Out + "NOT IMPELMENTED + "[Factor] + } + #else + #{ + # send Out [$Factor] + #} +} + +void rw_asm_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + rw_asm_abs_expr( Expr.E1 ) + rw_asm_abs_expr( Expr.E2 ) + + send Out + " popq %rcx + " popq %rax + + switch Expr.Op + case [`+] { + send Out + " addq %rcx, %rax + } + case [`-] { + send Out + " subq %rcx, %rax + } + case [`*] { + send Out + " imul %rcx, %rax + } + case [`==] { + send Out + " cmp %rcx, %rax + " sete %al + " movsbq %al, %rax + } + case [`!=] { + send Out + " cmp %rcx, %rax + " setne %al + " movsbq %al, %rax + } + case [`>=] { + send Out + " cmp %rcx, %rax + " setge %al + " movsbq %al, %rax + } + + send Out + " pushq %rax + } + else { + rw_asm_factor( Expr.factor ) + } +} + +void rw_asm_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_asm_abs_expr( AbsExpr ) +} + +int rw_asm_print_stmt( Stmt: indep::print_stmt ) +{ + switch Stmt + case [`print_int expr `;] { + rw_asm_expr( Stmt.expr ) + + send Out + " movq $.L_fmt_int, %rdi + " popq %rsi + " movq $0, %rax + " call printf + } + case [`print_buf E1: expr `, E2: expr `;] { + #send Out + # "fwrite( [rw_c_expr(E1)], 1, [rw_c_expr(E2)], stdout );" + } + case [`print_str expr `;] { + rw_asm_expr( Stmt.expr ) + + send Out + " movq $.L_fmt_str, %rdi + " popq %rsi + " movq $0, %rax + " call printf + } + case [`print_token `;] { + L1: int = Label + Label = Label + 1 + + L2: int = Label + Label = Label + 1 + + send Out + " movq -16(%rbp), %rax # ts + " movq -24(%rbp), %rcx # te + " subq %rax, %rcx # length + "[L1]: + " cmp $0, %rcx + " je [L2]f + " movsbl (%rax), %edi + " push %rax + " push %rcx + " call putchar + " pop %rcx + " pop %rax + " addq $1, %rax + " subq $1, %rcx + " jmp [L1]b + "[L2]: + " + } +} + +int rw_asm_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + switch ExprStmt + case [tk_ident opt_sub `= expr `;] + { + rw_asm_expr( ExprStmt.expr ) + + send Out + " popq %rax + " movq %rax, [ExprStmt.tk_ident](%rip) + } + case [expr `;] + { + rw_asm_expr( ExprStmt.expr ) + send Out + " popq %rax + } +} + +int rw_asm_if_stmt( IfStmt: indep::if_stmt ) +{ + L1: int = Label + Label = Label + 1 + + L2: int = Label + Label = Label + 1 + + rw_asm_expr( IfStmt.expr ) + + send Out + " popq %rax + " test %rax, %rax + " jz [L1]f + + rw_asm_stmt_list( IfStmt._repeat_stmt ) + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + " jmp [L2]f + "[L1]: + + rw_asm_stmt_list( IfStmt.opt_else._repeat_stmt ) + + send Out + "[L2]: + } + else { + send Out + "[L1]: + } + +} + +void rw_asm_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " movq $0, bpos(%rip) + } + case [`buf_append `( `) `;] { + send Out + " movq bpos(%rip), %rax + " movb (%r12), %cl + ' movb %cl, buf(%rax) + " addq $1, %rax + " movb $0, buf(%rax) + " movq %rax, bpos(%rip) + } +} + +int rw_asm_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + switch Stmt + case [`fexec E: expr `;] { + rw_asm_expr( E ) + + send Out + " popq %rax + " fexec %rax; + } + case [`fgoto `* E: expr `;] { + rw_asm_expr( E ) + send Out + "movq $0, %rax + "popq %rcx + "fgoto * %rcx; + } + case [`fnext `* E: expr `;] { + rw_asm_expr( E ) + send Out + "movq $0, %rax + "popq %rcx + "fnext * %rcx; + } + case [`fcall `* E: expr `;] { + rw_asm_expr( E ) + send Out + "movq $0, %rax + "popq %rcx + "fcall * %rcx; + } + case [`fncall `* E: expr `;] { + rw_asm_expr( E ) + send Out + "movq $0, %rax + "popq %rcx + "fncall * %rcx; + } + default { + send Out + "[Stmt] + } +} + +int rw_asm_stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] { + #rw_c_var_decl( Stmt.var_decl ) + } + case [expr_stmt] + rw_asm_expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + rw_asm_if_stmt( Stmt.if_stmt ) + case [print_stmt] + rw_asm_print_stmt( Stmt.print_stmt ) + case [buf_stmt] + rw_asm_buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + rw_asm_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_asm_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_asm_stmt( Stmt ) +} + +out_code::lines rw_asm_asm_action_block( ActionBlock: indep::action_block, ActionNum: int ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{ + " [rw_asm_stmt_list( ActionBlock._repeat_stmt )] + "} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{ + " [rw_asm_expr( ActionBlock.expr )] + " popq %rax + "} + } + send Out [] eos + return Out->tree +} + +int rw_asm_var_decl( VarDecl: indep::var_decl ) +{ + send Out + " .section .data + " .comm [VarDecl.tk_ident],8,8 + " .text +} + + +void rw_asm( Output: stream ) +{ + send Output + "# + "# @LANG: asm + "# @GENERATED: true + + if ProhibitGenflags { + send Output + "# @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + "# + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_asm_var_decl( Decl ) + send Out [] eos + + send Output + [Out->tree] + } + } + + ActionNum: int = 0 + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + Lines: out_code::lines = + rw_asm_asm_action_block( IndepActionBlock, ActionNum ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[Lines] + if ( !Action ) { + print( error, ': could not reparse action: ', Lines, '\n' ) + exit(1) + } + + ActionNum = ActionNum + 1 + } + + send Output + " + "[@Section] + " + " .text + " .comm buf, 1024, 32 + " .comm bpos, 8, 8 + " .comm stack_data, 1024, 32 + " .section .rodata + " + ".L_str_accept: + " .string \"ACCEPT\" + ".L_str_fail: + " .string \"FAIL\" + ".L_fmt_int: + " .string \"%ld\" + ".L_fmt_str: + " .string \"%s\" + " + " %% write data; + " + " .text + "exec: + " pushq %rbp + " movq %rsp, %rbp + " subq $96, %rsp + " + " movq $stack_data, -56(%rbp) + " + " pushq %r12 + " pushq %r13 + " movq %rdi, %r12 + + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_asm_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + " # Get the length. + " movq %r12, %rdi + " call strlen + " movq %r12, %r13 + " movslq %eax, %rax + " addq %rax, %r13 + " + " movq $0, bpos(%rip) + + if NeedsEof { + send Output + " movq %r13, -8(%rbp) + } + + send Output + " + " %% write init; + " %% write exec; + " + " # current state is in r11. + " movq [MachineName.word]_first_final(%rip), %rax + " cmpq %rax, %r11 + " jl .L_exec_fail + " movq $.L_str_accept, %rdi + " call puts + " jmp .L_exec_done + ".L_exec_fail: + " movq $.L_str_fail, %rdi + " call puts + ".L_exec_done: + " popq %r13 + " popq %r12 + " leave + " ret + + send Output + " .section .rodata + ".L_debug_msg: + " .string \"debug %d\\n\" + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + ".L_inp_[NR]: + " .string [^InputString] + NR = NR + 1 + } + + send Output + " + " .align 8 + "inp: + + NR = 0 + for InputString: indep::input_string in RagelTree { + send Output + " .quad .L_inp_[NR] + NR = NR + 1 + } + + send Output + " + + + send Output + " .align 8 + "inplen: + " .quad [NR] + " + + send Output + " .text + " .globl main + "main: + " pushq %rbp + " movq %rsp, %rbp + " pushq %r12 + " movq $0, %r12 + ".L_again: + " movq inplen(%rip), %rax + " cmpq %r12, %rax + " je .L_done + " movq inp(,%r12,8), %rdi + " call exec + " incq %r12 + " jmp .L_again + ".L_done: + " popq %r12 + " mov $0, %rax + " leave + " ret + "debug: + " movl %edi, %esi + " movq $0, %rax + " movq $.L_debug_msg, %rdi + " call printf + " ret + " +} diff --git a/test/trans.d/trans-c.lm b/test/trans.d/trans-c.lm new file mode 100644 index 00000000..563e1eec --- /dev/null +++ b/test/trans.d/trans-c.lm @@ -0,0 +1,346 @@ +int rw_c_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "ts\[0\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_c_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [rw_c_type(Factor.type)] ) ( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_c_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + else + { + send Out [$Factor] + } +} + +void rw_c_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "char *" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_c_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_c_abs_expr(Expr.E1)] [$Expr.Op] [rw_c_abs_expr( Expr.E2 )]" + } + else { + rw_c_factor( Expr.factor ) + } +} + +void rw_c_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_c_abs_expr( AbsExpr ) +} + +void rw_c_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_c_expr( OptArr.expr )]\]" + } +} + +int rw_c_var_decl( VarDecl: indep::var_decl ) +{ + send Out + "[rw_c_type( VarDecl.type )] [$VarDecl.tk_ident] [rw_c_opt_array(VarDecl.opt_arr)]; +} + +void rw_c_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_c_expr(OptSub.expr)]\]" +} + +int rw_c_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_c_opt_sub(ExprStmt.opt_sub)] = [rw_c_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_c_expr(ExprStmt.expr)]; + } +} + +int rw_c_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_c_expr( IfStmt.expr )] ) + "{ + " [rw_c_stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [rw_c_stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int rw_c_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "printf( \"%d\", [rw_c_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "fwrite( [rw_c_expr(E1)], 1, [rw_c_expr(E2)], stdout );" + } + else if match Stmt [`print_str expr `;] + { + send Out + "printf( \"%s\", [rw_c_expr( Stmt.expr )] ); + } + else if match Stmt [`print_token `;] + { + send Out + "fwrite ( ts , 1 , te - ts , stdout );" + } +} + +int rw_c_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +void rw_c_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen++\] = *p; + " buffer\[blen\] = 0; + } +} + + +int rw_c_stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + rw_c_var_decl( Stmt.var_decl ) + case [expr_stmt] + rw_c_expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + rw_c_if_stmt( Stmt.if_stmt ) + case [print_stmt] + rw_c_print_stmt( Stmt.print_stmt ) + case [buf_stmt] + rw_c_buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + rw_c_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_c_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_c_stmt( Stmt ) +} + +out_code::lines rw_c_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_c_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_c_expr( ActionBlock.expr )]} + } + send Out [] eos + return Out->tree +} + +void rw_c( Output: stream ) +{ + send Output + "/* + " * @LANG: c + " * @GENERATED: true + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " */ + " + "#include + "#include + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_c_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + Lines: out_code::lines = + rw_c_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[Lines] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + " + "[@Section] + " + "%% write data; + "int cs; + "int blen; + "char buffer\[1024\]; + " + "void init() + "{ + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_c_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + " + "void exec( char *data, int len ) + "{ + " char *p = data; + " char *pe = data + len; + + if NeedsEof { + send Output + " char *eof = pe; + } + + send Output + " %% write exec; + "} + " + "void finish( ) + "{ + " if ( cs >= [$MachineName.word]_first_final ) + " printf( \"ACCEPT\\n\" ); + " else + " printf( \"FAIL\\n\" ); + "} + " + + send Output + "char *inp\[\] = { + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "}; + " + + send Output + "int inplen = [NR]; + " + + send Output + "int main( ) + "{ + " int i; + " for ( i = 0; i < inplen; i++ ) { + " init(); + " exec( inp\[i\], strlen(inp\[i\]) ); + " finish(); + " } + " return 0; + "} + " + +# send Output +# "##### OUTPUT ##### +# +# for OutputLine: indep::output_line in RagelTree +# send Output [OutputLine] +} diff --git a/test/trans.d/trans-crack.lm b/test/trans.d/trans-crack.lm new file mode 100644 index 00000000..f9506cb6 --- /dev/null +++ b/test/trans.d/trans-crack.lm @@ -0,0 +1,346 @@ +namespace trans_crack + +int factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [type(Factor.type)] ( [expr(Factor.expr)] ) ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "buffer" + } + elsif match Factor [`blen] + { + send Out + "buffer.size" + } + else + { + send Out [$Factor] + } +} + +void type( Type: indep::type ) +{ + switch Type + case [`int] + { + send Out "int" + } + case [`bool] + { + send Out "int" + } + case [`char] + { + send Out "byte" + } + case [`ptr] + { + send Out "int + } + case [`byte] + { + send Out "byte" + } +} + +void abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[abs_expr(Expr.E1)] [$Expr.Op] [abs_expr( Expr.E2 )]" + } + else { + factor( Expr.factor ) + } +} + +void expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + abs_expr( AbsExpr ) +} + +void array_init( Size: int ) +{ + while ( Size > 1 ) { + send Out + "0, " + Size = Size - 1 + } + + if ( Size > 0 ) { + send Out + "0" + } +} + +int var_decl( VarDecl: indep::var_decl ) +{ + if VarDecl.opt_arr.expr { + send Out + "array\[[type( VarDecl.type )]\] [VarDecl.tk_ident] = " + "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \]; + } + else { + send Out + "[type( VarDecl.type )] [VarDecl.tk_ident]; + } +} + +void opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[expr(OptSub.expr)]\]" +} + +int expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident opt_sub(ExprStmt.opt_sub)] = [expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[expr(ExprStmt.expr)]; + } +} + +int if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [expr( IfStmt.expr )] ) + "{ + " [stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int print_stmt( Stmt: indep::print_stmt ) +{ + switch Stmt + case [`print_int expr `;] { + send Out + "cout.format( [expr(Stmt.expr)] ); + } + case [`print_buf E1: expr `, E2: expr `;] + { + send Out + "print!( \"{}\", buffer ); + } + case [`print_str expr `;] + { + send Out + "cout.format( [expr( Stmt.expr )] ); + } + case [`print_token `;] + { + send Out + "int len = uintz(te) - uintz(ts); + "cout.write( Buffer(data + uintz(ts), len) ); + } +} + +void buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " buffer = \"\"; + } + case [`buf_append `( `) `;] { + send Out + " buffer = buffer + fc; + } +} + + +int ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + var_decl( Stmt.var_decl ) + case [expr_stmt] + expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + if_stmt( Stmt.if_stmt ) + case [print_stmt] + print_stmt( Stmt.print_stmt ) + case [buf_stmt] + buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + ragel_stmt( Stmt.ragel_stmt ) +} + +void stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + stmt( Stmt ) +} + +int action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void crack( Output: stream ) +{ + # Translate action blocks. + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + "// + "// @LANG: crack + "// @GENERATED: true + + if ProhibitGenflags { + send Output + "// @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + "// + " + "import crack.io cout; + "import crack.lang Buffer; + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + "[@Section] + " + "%% write data; + " + "void m( String s ) + "{ + " byteptr data = s.buffer; + " int p = 0; + " int pe = s.size; + " int cs; + " String buffer; + + if NeedsEof { + send Output + " int eof = pe; + } + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + " %% write init; + " %% write exec; + " + " if ( cs >= [MachineName.word]_first_final ) { + " cout `ACCEPT\\n`; + " } + " else { + " cout `FAIL\\n`; + " } + "} + + send Output + ~ + ~void main() + ~{ + + for InputString: indep::input_string in RagelTree { + send Output + " m( [^InputString] ); + } + + send Output + ~} + ~ + ~main(); +} + +end diff --git a/test/trans.d/trans-csharp.lm b/test/trans.d/trans-csharp.lm new file mode 100644 index 00000000..5cd31085 --- /dev/null +++ b/test/trans.d/trans-csharp.lm @@ -0,0 +1,346 @@ +int rw_cs_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_cs_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_cs_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [rw_cs_type(Factor.type)] ) ( [rw_cs_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_cs_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "new String( buffer, 0, blen ) + } + else + { + send Out [$Factor] + } +} + +void rw_cs_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "int" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_cs_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_cs_abs_expr(Expr.E1)] [$Expr.Op] [rw_cs_abs_expr( Expr.E2 )]" + } + else { + rw_cs_factor( Expr.factor ) + } +} + +void rw_cs_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_cs_abs_expr( AbsExpr ) +} + +void rw_cs_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr + send Out "\[[rw_cs_expr( OptArr.expr )]\]" +} + +int rw_cs_var_decl( VarDecl: indep::var_decl ) +{ + if ( VarDecl.opt_arr.expr ) { + send Out + "[rw_cs_type( VarDecl.type )] \[\] [$VarDecl.tk_ident]" + " = new [rw_cs_type( VarDecl.type )] [rw_cs_opt_array(VarDecl.opt_arr) ]; + } + else { + send Out + "[rw_cs_type( VarDecl.type )] [$VarDecl.tk_ident]; + } +} + +void rw_cs_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) { + send Out "\[[rw_cs_expr(OptSub.expr)]\] + } +} + +int rw_cs_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_cs_opt_sub(ExprStmt.opt_sub)] = [rw_cs_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_cs_expr(ExprStmt.expr)]; + } +} + +int rw_cs_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_cs_expr( IfStmt.expr )] ) + "{ + " [rw_cs_stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [rw_cs_stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int rw_cs_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "Console.Write( [rw_cs_expr(Stmt.expr)] );" + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "Console.Write( new String( [rw_cs_expr(E1)], 0, [rw_cs_expr(E2)] ) );" + } + else if match Stmt [`print_str expr `;] + { + send Out + "Console.Write( [rw_cs_expr( Stmt.expr )] );" + } + else if match Stmt [`print_token `;] + { + send Out + "Console.Write( new String( data , ts , te - ts ) ); + } +} + +void rw_cs_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen++\] = fc; + } +} + + +int rw_cs_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int rw_cs_stmt( Stmt: indep::stmt ) +{ + if match Stmt [var_decl] + rw_cs_var_decl( Stmt.var_decl ) + else if match Stmt [expr_stmt] + rw_cs_expr_stmt( Stmt.expr_stmt ) + else if match Stmt [if_stmt] + rw_cs_if_stmt( Stmt.if_stmt ) + else if match Stmt [print_stmt] + rw_cs_print_stmt( Stmt.print_stmt ) + else if match Stmt [buf_stmt] + rw_cs_buf_stmt( Stmt.buf_stmt ) + else if match Stmt [ragel_stmt] + rw_cs_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_cs_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_cs_stmt( Stmt ) +} + +int rw_cs_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_cs_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_cs_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_csharp( Output: stream ) +{ + send Output + "/* + " * @LANG: csharp + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " * @GENERATED: true + " */ + " + "using System; + "// Disables lots of warnings that appear in the test suite + "#pragma warning disable 0168, 0169, 0219, 0162, 0414 + "namespace Test { + "class Test + "{ + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_cs_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + # Translate to specific language. + rw_cs_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + ["\n" @Section "\n"] + + send Output + "%% write data; + "int cs; + " + "void init() + "{ + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_cs_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + " + "void exec( char\[\] data, int len ) + "{ + " int p = 0; + " int pe = len; + " int eof = len; + " string _s; + " char \[\] buffer = new char \[1024\]; + " int blen = 0; + " %% write exec; + "} + " + "void finish( ) + "{ + " if ( cs >= [$MachineName.word]_first_final ) + " Console.WriteLine( \"ACCEPT\" ); + " else + " Console.WriteLine( \"FAIL\" ); + "} + " + + send Output + "static readonly string\[\] inp = { + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "}; + " + + send Output + " + "static readonly int inplen = [NR]; + " + "public static void Main (string\[\] args) + "{ + " Test machine = new Test(); + " for ( int i = 0; i < inplen; i++ ) { + " machine.init(); + " machine.exec( inp\[i\].ToCharArray(), inp\[i\].Length ); + " machine.finish(); + " } + "} + "} + "} +} diff --git a/test/trans.d/trans-d.lm b/test/trans.d/trans-d.lm new file mode 100644 index 00000000..674b0555 --- /dev/null +++ b/test/trans.d/trans-d.lm @@ -0,0 +1,332 @@ +int rw_d_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "ts\[0\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_d_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_d_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "cast( [rw_d_type(Factor.type)] ) ( [rw_d_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_d_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + else + { + send Out [$Factor] + } +} + +void rw_d_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "const(char) *" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_d_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_d_abs_expr(Expr.E1)] [$Expr.Op] [rw_d_abs_expr( Expr.E2 )]" + } + else { + rw_d_factor( Expr.factor ) + } +} + +void rw_d_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_d_abs_expr( AbsExpr ) +} + +void rw_d_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_d_expr( OptArr.expr )]\]" + } +} + +int rw_d_var_decl( VarDecl: indep::var_decl ) +{ + send Out + "[rw_d_type( VarDecl.type )] [$VarDecl.tk_ident][rw_d_opt_array(VarDecl.opt_arr)]; +} + +void rw_d_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_d_expr(OptSub.expr)]\]" +} + +int rw_d_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_d_opt_sub(ExprStmt.opt_sub)] = [rw_d_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_d_expr(ExprStmt.expr)]; + } +} + +int rw_d_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_d_expr( IfStmt.expr )] ) + "{ + " [rw_d_stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [rw_d_stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int rw_d_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "printf( \"%d\", [rw_d_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "printf( \"%.*s\", [rw_d_expr(E1)]\[0..([rw_d_expr(E2)])\] );" + } + else if match Stmt [`print_str expr `;] + { + send Out + "printf( \"%.*s\", [rw_d_expr(Stmt.expr)] );" + } + else if match Stmt [`print_token `;] + { + send Out + "printf( \"%.*s\", ts\[0..(te - ts)\] );" + } +} + +void rw_d_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen++\] = *p; + " buffer\[blen\] = 0; + } +} + +int rw_d_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int rw_d_stmt( Stmt: indep::stmt ) +{ + if match Stmt [var_decl] + rw_d_var_decl( Stmt.var_decl ) + else if match Stmt [expr_stmt] + rw_d_expr_stmt( Stmt.expr_stmt ) + else if match Stmt [if_stmt] + rw_d_if_stmt( Stmt.if_stmt ) + else if match Stmt [print_stmt] + rw_d_print_stmt( Stmt.print_stmt ) + else if match Stmt [buf_stmt] + rw_d_buf_stmt( Stmt.buf_stmt ) + else if match Stmt [ragel_stmt] + rw_d_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_d_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_d_stmt( Stmt ) +} + +int rw_d_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_d_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_d_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_d( Output: stream ) +{ + send Output + "/* + " * @LANG: d + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " * @GENERATED: true + " */ + " + "import std.stdio; + "import std.string; + " + "class [MachineName.word] + "{ + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_d_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + # Colm bug. + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + + rw_d_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + } + + send Output + " + "[@Section] + " + "%% write data; + "int cs; + "int blen; + "char buffer\[1024\]; + " + "void init() + "{ + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_d_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + + send Output + "void exec( const(char) data\[\] ) + "{ + " const(char) *p = data.ptr; + " const(char) *pe = data.ptr + data.length; + + if NeedsEof { + send Output + " const(char) *eof = pe; + } + + send Output + " char _s\[\]; + " + " %% write exec; + "} + " + "void finish( ) + "{ + " if ( cs >= [MachineName.word]_first_final ) + " writefln( \"ACCEPT\" ); + " else + " writefln( \"FAIL\" ); + "} + + send Output + ~static const char[][] inp = [ + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "\]; + " + "int inplen = [NR]; + " + "} + + send Output + "int main() + "{ + " [MachineName.word] m = new [MachineName.word](); + " int i; + " for ( i = 0; i < m.inplen; i++ ) { + " m.init(); + " m.exec( m.inp\[i\] ); + " m.finish(); + " } + " return 0; + "} + " +} diff --git a/test/trans.d/trans-go.lm b/test/trans.d/trans-go.lm new file mode 100644 index 00000000..30a5600f --- /dev/null +++ b/test/trans.d/trans-go.lm @@ -0,0 +1,322 @@ +int rw_go_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_go_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_go_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [rw_go_type(Factor.type)] ) ( [rw_go_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_go_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "string ( buffer\[:blen\] )" + } + else + { + send Out [$Factor] + } +} + +void rw_go_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "byte" + } + elsif match Type [`ptr] + { + send Out "int" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_go_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_go_abs_expr(Expr.E1)] [$Expr.Op] [rw_go_abs_expr( Expr.E2 )]" + } + else { + rw_go_factor( Expr.factor ) + } +} + +void rw_go_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_go_abs_expr( AbsExpr ) +} + +void rw_go_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_go_expr( OptArr.expr )]\]" + } +} + +int rw_go_var_decl( VarDecl: indep::var_decl ) +{ + send Out + "var [$VarDecl.tk_ident] [rw_go_opt_array(VarDecl.opt_arr)] [rw_go_type( VarDecl.type )] ; +} + +void rw_go_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_go_expr(OptSub.expr)]\]" +} + +int rw_go_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_go_opt_sub(ExprStmt.opt_sub)] = [rw_go_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_go_expr(ExprStmt.expr)]; + } +} + +int rw_go_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_go_expr( IfStmt.expr )] ) { + " [rw_go_stmt_list( IfStmt._repeat_stmt )] + "}" + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + " else { + " [rw_go_stmt_list( IfStmt.opt_else._repeat_stmt )] + "}" + } + + send Out " +} + +int rw_go_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "fmt.Print( [rw_go_expr(Stmt.expr)] );" + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "fmt.Print( string ( [rw_go_expr(E1)]\[:[rw_go_expr(E2)]\] ));" + } + else if match Stmt [`print_str expr `;] + { + send Out + "fmt.Print( [rw_go_expr( Stmt.expr )] );" + } + else if match Stmt [`print_token `;] + { + send Out + "fmt.Print( data\[ts:te\] );" + } +} + +int rw_go_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + "[Stmt] +} + +void rw_go_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen\] = fc; + " blen += 1; + " buffer\[blen\] = 0; + } +} + + +int rw_go_stmt( Stmt: indep::stmt ) +{ + if match Stmt [var_decl] + rw_go_var_decl( Stmt.var_decl ) + else if match Stmt [expr_stmt] + rw_go_expr_stmt( Stmt.expr_stmt ) + else if match Stmt [if_stmt] + rw_go_if_stmt( Stmt.if_stmt ) + else if match Stmt [print_stmt] + rw_go_print_stmt( Stmt.print_stmt ) + else if match Stmt [buf_stmt] + rw_go_buf_stmt( Stmt.buf_stmt ) + else if match Stmt [ragel_stmt] + rw_go_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_go_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_go_stmt( Stmt ) +} + +int rw_go_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_go_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_go_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_go( Output: stream ) +{ + send Output + "/* + " * @LANG: go + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " * @GENERATED: true + " */ + " + "package main + "import \"fmt\" + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_go_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + + # Translate to specific language. + rw_go_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + } + + send Output ['\n' @Section '\n'] + + send Output + "var cs int; + "var blen int; + "var buffer \[1024\] byte; + " + "%% write data; + " + "func prepare() { + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_go_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + " + "func exec(data string) { + " var p int = 0 + " var pe int = len(data) + + if NeedsEof { + send Output + " var eof int = pe + } + + send Output + " %% write exec; + "} + "func finish() { + " if cs >= [MachineName.word]_first_final { + " fmt.Println(\"ACCEPT\") + " } else { + " fmt.Println(\"FAIL\") + " } + "} + + send Output + ~var inp []string = []string { + + for InputString: indep::input_string in RagelTree { + send Output [^InputString ",\n"] + } + + send Output + "}; + " + + send Output + "func main() { + " for _, data := range inp { + " prepare() + " exec(data) + " finish() + " } + "} +} diff --git a/test/trans.d/trans-java.lm b/test/trans.d/trans-java.lm new file mode 100644 index 00000000..99c1b486 --- /dev/null +++ b/test/trans.d/trans-java.lm @@ -0,0 +1,346 @@ +int rw_java_factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [rw_java_expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [rw_java_expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( [rw_java_type(Factor.type)] ) ( [rw_java_expr(Factor.expr)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [rw_java_expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "new String( buffer, 0, blen )" + } + else + { + send Out [$Factor] + } +} + +void rw_java_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "int + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_java_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_java_abs_expr(Expr.E1)] [$Expr.Op] [rw_java_abs_expr( Expr.E2 )]" + } + else { + rw_java_factor( Expr.factor ) + } +} + +void rw_java_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_java_abs_expr( AbsExpr ) +} + +void rw_java_opt_array( OptArr: indep::opt_arr, Type: indep::type ) +{ + if OptArr.expr { + send Out "\[\] = new [rw_java_type( Type )]\[[rw_java_expr( OptArr.expr )]\]" + } +} + +int rw_java_var_decl( VarDecl: indep::var_decl ) +{ + send Out + "[rw_java_type( VarDecl.type )] [$VarDecl.tk_ident] [rw_java_opt_array(VarDecl.opt_arr, VarDecl.type)]; +} + +void rw_java_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_java_expr(OptSub.expr)]\]" +} + +int rw_java_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_java_opt_sub(ExprStmt.opt_sub)] = [rw_java_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_java_expr(ExprStmt.expr)]; + } +} + +int rw_java_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_java_expr( IfStmt.expr )] ) + "{ + " [rw_java_stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [rw_java_stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int rw_java_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "System.out.print( [rw_java_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "_s = new String( [rw_java_expr(E1)], 0, [rw_java_expr(E2)] ); + "System.out.print( _s ); + } + else if match Stmt [`print_str expr `;] + { + send Out + "System.out.print( [rw_java_expr( Stmt.expr )] ); + } + else if match Stmt [`print_token `;] + { + send Out + "_s = new String( data, ts, te - ts ); + "System.out.print( _s ); + } +} + +void rw_java_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen\] = fc; + " blen += 1; + } +} + + +int rw_java_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int rw_java_stmt( Stmt: indep::stmt ) +{ + if match Stmt [var_decl] + rw_java_var_decl( Stmt.var_decl ) + else if match Stmt [expr_stmt] + rw_java_expr_stmt( Stmt.expr_stmt ) + else if match Stmt [if_stmt] + rw_java_if_stmt( Stmt.if_stmt ) + else if match Stmt [print_stmt] + rw_java_print_stmt( Stmt.print_stmt ) + else if match Stmt [buf_stmt] + rw_java_buf_stmt( Stmt.buf_stmt ) + else if match Stmt [ragel_stmt] + rw_java_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_java_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_java_stmt( Stmt ) +} + +int rw_java_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_java_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_java_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_java( Output: stream ) +{ + # Translate action blocks. + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + rw_java_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + "/* + " * @LANG: java + " * @GENERATED: true + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " */ + " + " + "class [ClassName] + "{ + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_java_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + "[@Section] + " + "%% write data; + "int cs; + " + "void init() + "{ + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_java_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + "} + " + "void exec( char data\[\], int len ) + "{ + " char buffer \[\] = new char\[1024\]; + " int blen = 0; + " int p = 0; + " int pe = len; + " + + if NeedsEof { + send Output + " int eof = len; + } + + send Output + " String _s; + " %% write exec; + "} + " + "void finish( ) + "{ + " if ( cs >= [MachineName.word]_first_final ) + " System.out.println( \"ACCEPT\" ); + " else + " System.out.println( \"FAIL\" ); + "} + " + + send Output + "static final String inp\[\] = { + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "}; + " + + send Output + "static final int inplen = [NR]; + " + + send Output + "public static void main (String\[\] args) + "{ + " [ClassName] machine = new [ClassName](); + " for ( int i = 0; i < inplen; i++ ) { + " machine.init(); + " machine.exec( inp\[i\].toCharArray(), inp\[i\].length() ); + " machine.finish(); + " } + "} + "} +} diff --git a/test/trans.d/trans-julia.lm b/test/trans.d/trans-julia.lm new file mode 100644 index 00000000..ed918dbb --- /dev/null +++ b/test/trans.d/trans-julia.lm @@ -0,0 +1,332 @@ +namespace trans_julia + +int factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts+1\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "convert( [type(Factor.type)], ( [expr(Factor.expr)] ) ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "buffer" + } + elsif match Factor [`blen] + { + send Out + "length(buffer)" + } + else + { + send Out [$Factor] + } +} + +void type( Type: indep::type ) +{ + switch Type + case [`int] + { + send Out "Int" + } + case [`bool] + { + send Out "Int8" + } + case [`char] + { + send Out "Uint8" + } + case [`ptr] + { + send Out "i32 + } + case [`byte] + { + send Out "unsigned char" + } +} + +void abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[abs_expr(Expr.E1)] [$Expr.Op] [abs_expr( Expr.E2 )]" + } + else { + factor( Expr.factor ) + } +} + +void expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + abs_expr( AbsExpr ) +} + +void array_init( Size: int ) +{ + while ( Size > 1 ) { + send Out + "0, " + Size = Size - 1 + } + + if ( Size > 0 ) { + send Out + "0" + } +} + +int var_decl( VarDecl: indep::var_decl ) +{ + if VarDecl.opt_arr.expr { + send Out + "[VarDecl.tk_ident] = [type( VarDecl.type )] " + "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \]; + } + else { + send Out + "[VarDecl.tk_ident] = 0; + } +} + +void opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[expr(OptSub.expr)]\]" +} + +int expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident opt_sub(ExprStmt.opt_sub)] = [expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[expr(ExprStmt.expr)]; + } +} + +int if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [expr( IfStmt.expr )] ) + " [stmt_list( IfStmt._repeat_stmt )] + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else + " [stmt_list( IfStmt.opt_else._repeat_stmt )] + } + + send Out + "end +} + +int print_stmt( Stmt: indep::print_stmt ) +{ + switch Stmt + case [`print_int expr `;] { + send Out + "print( [expr(Stmt.expr)] ); + } + case [`print_buf E1: expr `, E2: expr `;] + { + send Out + "print( buffer ); + } + case [`print_str expr `;] + { + send Out + "print( [expr( Stmt.expr )] ); + } + case [`print_token `;] + { + send Out + "print( data\[(ts+1) : (te)\] ) + } +} + +void buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " buffer = \"\"; + } + case [`buf_append `( `) `;] { + send Out + " buffer = buffer * AbstractString(Char\[fc\]); + } +} + + +int ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + var_decl( Stmt.var_decl ) + case [expr_stmt] + expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + if_stmt( Stmt.if_stmt ) + case [print_stmt] + print_stmt( Stmt.print_stmt ) + case [buf_stmt] + buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + ragel_stmt( Stmt.ragel_stmt ) +} + +void stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + stmt( Stmt ) +} + +int action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void julia( Output: stream ) +{ + # Translate action blocks. + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + "// + "// @LANG: julia + "// @GENERATED: true + + if ProhibitGenflags { + send Output + "// @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + "// + " + + + send Output + " + "[@Section] + " + "%% write data; + " + "function m( data::AbstractString ) + " p = 0 + " pe = length(data) + " eof = length(data) + " cs = 0 + " buffer = \"\" + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + " %% write init; + " %% write exec; + " + " if ( cs >= [MachineName.word]_first_final ) + " println( \"ACCEPT\" ); + " else + " println( \"FAIL\" ); + " end + "end + + + + send Output + ~ + + for InputString: indep::input_string in RagelTree { + send Output + " m( [^InputString] ); + } + +} + +end diff --git a/test/trans.d/trans-ocaml.lm b/test/trans.d/trans-ocaml.lm new file mode 100644 index 00000000..4298637f --- /dev/null +++ b/test/trans.d/trans-ocaml.lm @@ -0,0 +1,362 @@ +int rw_ocaml_factor( Factor: indep::factor ) +{ + switch Factor + case [`first_token_char] { + send Out + "( Char.code data.\[ts.contents\] )" + } + case [tk_ident `[ expr `]] { + send Out + "[$Factor.tk_ident]\[ [rw_ocaml_expr(Factor.expr)] \] + } + case [ `fentry `( E: expr `)] { + send Out + "fentry( [E] )" + } + case [tk_ident `( expr `)] { + send Out + "[$Factor.tk_ident]( [rw_ocaml_expr(Factor.expr)] ) + } + case [`< type `> `( expr `)] { + send Out + "( [rw_ocaml_expr(Factor.expr)] ) + } + case [`( expr `)] { + send Out + "( [rw_ocaml_expr(Factor.expr)] ) + } + case ['true'] { + send Out '1' + } + case ['false'] { + send Out '0' + } + case "'0'" { + send Out + "( Char.code '0' )" + } + case "'a'" { + send Out + "( Char.code 'a' )" + } + case [`fc] { + send Out + "fc" + } + case [tk_ident] { + send Out + "[Factor.tk_ident].contents" + } + case [`buffer] + { + send Out + "String.sub buffer 0 blen.contents" + } + case [`blen] + { + send Out + "blen.contents" + } + default { + send Out + [Factor] + } +} + +void rw_ocaml_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "char *" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_ocaml_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_ocaml_abs_expr(Expr.E1)] [$Expr.Op] [rw_ocaml_abs_expr( Expr.E2 )]" + } + else { + rw_ocaml_factor( Expr.factor ) + } +} + +void rw_ocaml_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_ocaml_abs_expr( AbsExpr ) +} + +void rw_ocaml_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_ocaml_expr( OptArr.expr )]\]" + } +} + +int rw_ocaml_var_decl( VarDecl: indep::var_decl ) +{ + if match VarDecl.opt_arr [] { + send Out + "let [$VarDecl.tk_ident] = ref 0 + } + else { + send Out + "let [$VarDecl.tk_ident] = Array.make 32 0 + } +} + +void rw_ocaml_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_ocaml_expr(OptSub.expr)]\]" +} + +int rw_ocaml_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + if match ExprStmt.opt_sub [] { + send Out + "[$ExprStmt.tk_ident rw_ocaml_opt_sub(ExprStmt.opt_sub)] := [rw_ocaml_expr(ExprStmt.expr)]; + } + else { + send Out + "Array.set [$ExprStmt.tk_ident] [rw_ocaml_expr(ExprStmt.opt_sub.expr)] [rw_ocaml_expr(ExprStmt.expr)]; + + } + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_ocaml_expr(ExprStmt.expr)]; + } +} + +int rw_ocaml_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if [rw_ocaml_expr( IfStmt.expr )] then + "begin + " [rw_ocaml_stmt_list( IfStmt._repeat_stmt )] + "end + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else + "begin + " [rw_ocaml_stmt_list( IfStmt.opt_else._repeat_stmt )] + "end + } + send Out + "; +} + +int rw_ocaml_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "print_int( [rw_ocaml_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "for i = 0 to [rw_ocaml_expr(E2)] - 1 do print_char (Char.chr [E1].(i)) done; " + } + else if match Stmt [`print_str expr `;] + { + send Out + "print_string( [rw_ocaml_expr( Stmt.expr )] ); + } + else if match Stmt [`print_token `;] + { + send Out + "for i = ts.contents to te.contents - 1 do print_char data.\[i\] done; " + } +} + +void rw_ocaml_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + "begin + " blen := 0; + "end + } + case [`buf_append `( `) `;] { + send Out + " begin + " String.set buffer blen.contents data.\[p.contents\]; + " blen := blen.contents + 1; + " end + } +} + +int rw_ocaml_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + switch Stmt + case [`fnext `* E: expr `;] { + send Out + "fnext *[rw_ocaml_expr(E)]; + } + case [`fncall `* E: expr `;] { + send Out + "fncall *[rw_ocaml_expr(E)]; + } + default { + send Out + [Stmt] + } +} + +int rw_ocaml_stmt( Stmt: indep::stmt ) +{ + if match Stmt [var_decl] + rw_ocaml_var_decl( Stmt.var_decl ) + else if match Stmt [expr_stmt] + rw_ocaml_expr_stmt( Stmt.expr_stmt ) + else if match Stmt [if_stmt] + rw_ocaml_if_stmt( Stmt.if_stmt ) + else if match Stmt [print_stmt] + rw_ocaml_print_stmt( Stmt.print_stmt ) + else if match Stmt [buf_stmt] + rw_ocaml_buf_stmt( Stmt.buf_stmt ) + else if match Stmt [ragel_stmt] + rw_ocaml_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_ocaml_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_ocaml_stmt( Stmt ) +} + +int rw_ocaml_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_ocaml_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_ocaml_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_ocaml( Output: stream ) +{ + send Output + "(* + " * @LANG: ocaml + " * @GENERATED: true + + if ProhibitGenflags { + send Output + " * @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + " *) + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_ocaml_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( "error parsing indep action block: ", error, '\n', Action ) + exit(1) + } + + rw_ocaml_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( "error parsing ragel action block: ", error, '\n', $Out->tree ) + exit(1) + } + } + + send Output + " + "[@Section] + " + " + "%% write data; + " + "let exec data = + " let buffer = String.create(1024) in + " let blen :int ref = ref 0 in + " let cs = ref 0 in + " let p = ref 0 in + " let pe = ref (String.length data) in + + if NeedsEof { + send Output + " let eof = pe in + } + + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_ocaml_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + " %% write exec; + " if !cs >= [MachineName.word]_first_final then + " print_string \"ACCEPT\\n\" + " else + " print_string \"FAIL\\n\" + ";; + " + + send Output + "let () = + + for InputString: indep::input_string in RagelTree { + send Output + " exec [^InputString]; + } + + send Output + " () + ";; + " +} diff --git a/test/trans.d/trans-ruby.lm b/test/trans.d/trans-ruby.lm new file mode 100644 index 00000000..df0f346c --- /dev/null +++ b/test/trans.d/trans-ruby.lm @@ -0,0 +1,336 @@ +int rw_ruby_factor( Factor: indep::factor ) +{ + switch Factor + case [`first_token_char] { + send Out "data\[ts\].ord" + } + case [tk_ident `[ expr `]] { + send Out + "[$Factor.tk_ident]\[ [rw_ruby_expr(Factor.expr)] \] + } + case [tk_ident `( expr `)] { + send Out + "[$Factor.tk_ident]( [rw_ruby_expr(Factor.expr)] ) + } + case [`< type `> `( expr `)] { + send Out + "( [rw_ruby_expr(Factor.expr)] ) + } + case [`( expr `)] { + send Out + "( [rw_ruby_expr(Factor.expr)] ) + } + case ['true'] { + send Out '1' + } + case ['false'] { + send Out '0' + } + case "'0'" { + send Out '"0"[0].ord' + } + case "'a'" { + send Out '"a"[0].ord' + } + case [`buffer] { + send Out + "buffer\[0..blen-1\].pack( \"c*\" )" + } + default { + send Out [$Factor] + } +} + +void rw_ruby_type( Type: indep::type ) +{ + if match Type [`int] + { + send Out "int" + } + elsif match Type [`bool] + { + send Out "int" + } + elsif match Type [`char] + { + send Out "char" + } + elsif match Type [`ptr] + { + send Out "char *" + } + elsif match Type [`byte] + { + send Out "unsigned char" + } +} + +void rw_ruby_abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[rw_ruby_abs_expr(Expr.E1)] [$Expr.Op] [rw_ruby_abs_expr( Expr.E2 )]" + } + else { + rw_ruby_factor( Expr.factor ) + } +} + +void rw_ruby_expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + rw_ruby_abs_expr( AbsExpr ) +} + +void rw_ruby_opt_array( OptArr: indep::opt_arr ) +{ + if OptArr.expr { + send Out "\[[rw_ruby_expr( OptArr.expr )]\]" + } +} + +int rw_ruby_var_decl( VarDecl: indep::var_decl ) +{ + OptArr: indep::opt_arr = VarDecl.opt_arr + if OptArr.expr { + send Out + "[$VarDecl.tk_ident] = Array.new + } + else { + send Out + "[$VarDecl.tk_ident] = 1 + } +} + +void rw_ruby_opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[rw_ruby_expr(OptSub.expr)]\]" +} + +int rw_ruby_expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident rw_ruby_opt_sub(ExprStmt.opt_sub)] = [rw_ruby_expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[rw_ruby_expr(ExprStmt.expr)]; + } +} + +int rw_ruby_if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [rw_ruby_expr( IfStmt.expr )] ) + " [rw_ruby_stmt_list( IfStmt._repeat_stmt )] + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else + " [rw_ruby_stmt_list( IfStmt.opt_else._repeat_stmt )] + } + send Out + "end +} + +int rw_ruby_print_stmt( Stmt: indep::print_stmt ) +{ + if match Stmt [`print_int expr `;] { + send Out + "print( [rw_ruby_expr(Stmt.expr)] ); + } + else if match Stmt [`print_buf E1: expr `, E2: expr `;] + { + send Out + "_a = [rw_ruby_expr(E1)] \[0..pos-1\] ; + "print( _a.pack( \"c*\" ) ); + } + else if match Stmt [`print_str expr `;] + { + send Out + "print( [rw_ruby_expr( Stmt.expr )] ); + } + else if match Stmt [`print_token `;] + { + send Out + "_m = data\[ts..te-1\]; + "print( _m ); + } +} + +int rw_ruby_ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +void rw_ruby_buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " blen = 0; + } + case [`buf_append `( `) `;] { + send Out + " buffer\[blen\] = fc; + " blen += 1; + } +} + +int rw_ruby_stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + rw_ruby_var_decl( Stmt.var_decl ) + case [expr_stmt] + rw_ruby_expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + rw_ruby_if_stmt( Stmt.if_stmt ) + case [print_stmt] + rw_ruby_print_stmt( Stmt.print_stmt ) + case [buf_stmt] + rw_ruby_buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + rw_ruby_ragel_stmt( Stmt.ragel_stmt ) +} + +void rw_ruby_stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + rw_ruby_stmt( Stmt ) +} + +int rw_ruby_action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[rw_ruby_stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[rw_ruby_expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rw_ruby( Output: stream ) +{ + Section: indep::section = RagelTree.section + + # Lowercase the machine name + for MachineName: ragel::machine_name in Section { + for Word: ragel::word in MachineName { + Word.data = tolower( Word.data ) + } + } + + MachineName = ragel::machine_name in Section + + # Rewrite the action blocks. + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + rw_ruby_action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + + send Output + "# + "# @LANG: ruby + "# @GENERATED: true + + if ProhibitGenflags { + send Output + "# @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + "# + " + + send Output + " + "[@Section] + " + "%% write data; + " + "def run_machine( data ) + " p = 0 + " pe = data.length + " eof = data.length + " cs = 0; + " _m = "" + " _a = "" + " buffer = Array.new + " blen = 0 + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + rw_ruby_var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + rw_ruby_expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " %% write init; + " %% write exec; + " if cs >= [MachineName.word]_first_final + " puts \"ACCEPT\" + " else + " puts \"FAIL\" + " end + "end + " + + send Output + "inp = \[ + + NR: int = 0 + for InputString: indep::input_string in RagelTree { + send Output + [^InputString ",\n"] + NR = NR + 1 + } + + send Output + "\] + " + + send Output + "inplen = [NR] + " + + send Output + "inp.each { |str| run_machine(str) } + " +} diff --git a/test/trans.d/trans-rust.lm b/test/trans.d/trans-rust.lm new file mode 100644 index 00000000..b75f672b --- /dev/null +++ b/test/trans.d/trans-rust.lm @@ -0,0 +1,344 @@ +namespace trans_rust + +int factor( Factor: indep::factor ) +{ + if match Factor [`first_token_char] + { + send Out "data\[ts as usize\]" + } + else if match Factor [tk_ident `[ expr `]] + { + send Out + "[$Factor.tk_ident]\[ [expr(Factor.expr)] \] + } + else if match Factor [tk_ident `( expr `)] + { + send Out + "[$Factor.tk_ident]( [expr(Factor.expr)] ) + } + elsif match Factor [`< type `> `( expr `)] + { + send Out + "( ( [expr(Factor.expr)] ) as [type(Factor.type)] ) + } + elsif match Factor [`( expr `)] + { + send Out + "( [expr(Factor.expr)] ) + } + elsif match Factor ['true'] + { + send Out '1' + } + elsif match Factor ['false'] + { + send Out '0' + } + elsif match Factor [`buffer] + { + send Out + "buffer" + } + elsif match Factor [`blen] + { + send Out + "buffer.len()" + } + else + { + send Out [$Factor] + } +} + +void type( Type: indep::type ) +{ + switch Type + case [`int] + { + send Out "i32" + } + case [`bool] + { + send Out "i8" + } + case [`char] + { + send Out "u8" + } + case [`ptr] + { + send Out "i32 + } + case [`byte] + { + send Out "unsigned char" + } +} + +void abs_expr( Expr: indep::abs_expr ) +{ + if ( Expr.Op ) { + send Out + "[abs_expr(Expr.E1)] [$Expr.Op] [abs_expr( Expr.E2 )]" + } + else { + factor( Expr.factor ) + } +} + +void expr( Expr: indep::expr ) +{ + AbsExpr: indep::abs_expr = indep::abs_comparative( Expr.comparative ) + abs_expr( AbsExpr ) +} + +void array_init( Size: int ) +{ + while ( Size > 1 ) { + send Out + "0, " + Size = Size - 1 + } + + if ( Size > 0 ) { + send Out + "0" + } +} + +int var_decl( VarDecl: indep::var_decl ) +{ + if VarDecl.opt_arr.expr { + send Out + "static mut [VarDecl.tk_ident] : " + "\[ [type( VarDecl.type )] ; [expr( VarDecl.opt_arr.expr )]\] = " + "\[ [array_init( atoi($VarDecl.opt_arr.expr) )] \]; + } + else { + send Out + "static mut [VarDecl.tk_ident] : [type( VarDecl.type )] = 0; + } +} + +void opt_sub( OptSub: indep::opt_sub ) +{ + if ( OptSub.expr ) + send Out "\[[expr(OptSub.expr)]\]" +} + +int expr_stmt( ExprStmt: indep::expr_stmt ) +{ + if match ExprStmt [tk_ident opt_sub `= expr `;] + { + send Out + "[$ExprStmt.tk_ident opt_sub(ExprStmt.opt_sub)] = [expr(ExprStmt.expr)]; + } + else if match ExprStmt [expr `;] + { + send Out + "[expr(ExprStmt.expr)]; + } +} + +int if_stmt( IfStmt: indep::if_stmt ) +{ + send Out + "if ( [expr( IfStmt.expr )] ) + "{ + " [stmt_list( IfStmt._repeat_stmt )] + "} + + if ( IfStmt.opt_else._repeat_stmt ) { + send Out + "else { + " [stmt_list( IfStmt.opt_else._repeat_stmt )] + "} + } +} + +int print_stmt( Stmt: indep::print_stmt ) +{ + switch Stmt + case [`print_int expr `;] { + send Out + "print!( \"{}\", [expr(Stmt.expr)] ); + } + case [`print_buf E1: expr `, E2: expr `;] + { + send Out + "print!( \"{}\", buffer ); + } + case [`print_str expr `;] + { + send Out + "print!( \"{}\", [expr( Stmt.expr )] ); + } + case [`print_token `;] + { + send Out + "let s = match std::str::from_utf8(&data\[ts as usize .. te as usize\]) { + " Ok(v) => v, + " Err(e) => panic!(\"Invalid UTF-8 sequence: {}\", e), + " }; + "print!( \"{}\", s ); + } +} + +void buf_stmt( BufStmt: indep::buf_stmt ) +{ + switch BufStmt + case [`buf_clear `( `) `;] { + send Out + " buffer = String::new(); + } + case [`buf_append `( `) `;] { + send Out + " buffer.push( ( fc ) as char ); + } +} + + +int ragel_stmt( Stmt: indep::ragel_stmt ) +{ + send Out + [$Stmt] +} + +int stmt( Stmt: indep::stmt ) +{ + switch Stmt + case [var_decl] + var_decl( Stmt.var_decl ) + case [expr_stmt] + expr_stmt( Stmt.expr_stmt ) + case [if_stmt] + if_stmt( Stmt.if_stmt ) + case [print_stmt] + print_stmt( Stmt.print_stmt ) + case [buf_stmt] + buf_stmt( Stmt.buf_stmt ) + case [ragel_stmt] + ragel_stmt( Stmt.ragel_stmt ) +} + +void stmt_list( StmtList: indep::stmt* ) +{ + for Stmt: indep::stmt in repeat( StmtList ) + stmt( Stmt ) +} + +int action_block( ActionBlock: indep::action_block ) +{ + Out = new parser() + if match ActionBlock [`{ stmt* `}] { + send Out + "{[stmt_list( ActionBlock._repeat_stmt )]} + } + else if match ActionBlock [`{ expr `}] { + send Out + "{[expr( ActionBlock.expr )]} + } + send Out [] eos +} + +void rust( Output: stream ) +{ + # Translate action blocks. + Section: indep::section = RagelTree.section + for Action: ragel::action_block in Section { + # Reparse as lang-independent code. + parse IndepActionBlock: indep::action_block[$Action] + if ( !IndepActionBlock ) { + print( error, '\n', Action ) + exit(1) + } + + action_block( IndepActionBlock ) + + # Reparse back to ragel action block. + Action = parse ragel::action_block[$Out->tree] + if ( !Action ) { + print( error, '\n' ) + exit(1) + } + } + + send Output + "// + "// @LANG: rust + "// @GENERATED: true + + if ProhibitGenflags { + send Output + "// @PROHIBIT_GENFLAGS:[ProhibitGenflags] + } + + send Output + "// + " + + Init: indep::stmt* = RagelTree.Init + for Stmt: indep::stmt in Init { + if match Stmt [Decl: var_decl] { + Out = new parser() + var_decl( Decl ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + "[@Section] + " + "%% write data; + " + "unsafe fn m( s: String ) + "{ + " let data: &\[u8\] = s.as_bytes(); + " let mut p:i32 = 0; + " let mut pe:i32 = s.len() as i32; + " let mut eof:i32 = s.len() as i32; + " let mut cs: i32 = 0; + " let mut buffer = String::new(); + + for Stmt: indep::stmt in Init { + if match Stmt [ExprStmt: expr_stmt] { + Out = new parser() + expr_stmt( ExprStmt ) + send Out [] eos + send Output [Out->tree] + } + } + + send Output + " + " %% write init; + " %% write exec; + " + " if ( cs >= [MachineName.word]_first_final ) { + " println!( \"ACCEPT\" ); + " } + " else { + " println!( \"FAIL\" ); + " } + "} + + + + send Output + ~ + ~fn main() + ~{ + + for InputString: indep::input_string in RagelTree { + send Output + " unsafe { m( [^InputString].to_string() ); } + } + + send Output + ~} + ~ +} + +end diff --git a/test/trans.d/trans.lm b/test/trans.d/trans.lm new file mode 100644 index 00000000..b9fa5870 --- /dev/null +++ b/test/trans.d/trans.lm @@ -0,0 +1,366 @@ +include 'ragel.lm' +include 'ragel-c.lm' +include 'ragel-ocaml.lm' +include 'ragel-ruby.lm' +include 'ragel-crack.lm' + +namespace indep + # Opening the test case header. + lex + ignore / ( [ \t] | NL )+ / + + token c_comm_open + / '/*' / + end + + # Contents of test case heaer. + lex + token comm_name /'@' [A-Za-z0-9_]+ ':' / + token comm_term /'*/'/ + token comm_any / any / + end + + token comm_val /[^\n]* '\n' / + + lex + literal `%%{ `}%% + + literal `int `bool `char `ptr `byte `if `else + `print_int `print_buf `print_str `print_token + `first_token_char `buffer `blen `buf_append `buf_clear + + literal `fpc `fc `fcurs `ftargs `fentry + `fhold `fexec `fgoto `fnext `fcall + `fret `fbreak `fncall `fnret `fnbreak + + literal `; `< `> `( `) `[ `] `= + `* `! `{ `} `+ `- `== `!= + `>= `<= `, + + ignore / ( [ \t] | NL )+ / + + token tk_ident /ident/ + token tk_number /digit+/ + token tk_hex_number /'0x' [0-9a-fA-F]+/ + + rl INPUT /'INPUT'/ + rl OUTPUT /'OUTPUT'/ + + token sect_INPUT + / '#'+ ' '* INPUT ' '* '#'+ '\n' / + + token sect_OUTPUT + / '#'+ ' '* OUTPUT ' '* '#'+ '\n' / -ni + + token string + / s_literal | d_literal / + + ignore / cpp_comment / + ignore / c_comment / + end + + lex + token output_line /[^\n]* '\n'/ + end + + def comm_def + [comm_name comm_val] + + def comm_item + [comm_def] + | [comm_any] + + def test_header + [c_comm_open comm_item* comm_term] + + def input_string + [string] + + def input_list + [input_list input_string] + | [input_string] + + def input + [input_list] + + def output + [output_line*] + + def factor + [`first_token_char] + | [`buffer] + | [`blen] + | [tk_ident] + | [tk_ident `[ expr `]] + | [tk_ident `( expr `)] + | [tk_number] + | [`- tk_number] + | [tk_hex_number] + | [string] + | [`< type `> `( expr `)] + | [`( expr `)] + | [ragel_factor] + + def ragel_factor + [`fentry `( expr `)] + | [`fc] + | [`fcurs] + | [`ftargs] + + def mult_op + [`*] + + def add_op + [`+] + | [`-] + + def cmp_op + [`<] + | [`>] + | [`!=] + | [`==] + | [`<=] + | [`>=] + + def abs_op + [mult_op] + | [add_op] + | [cmp_op] + + abs_expr abs_multiplicative( Expr: indep::multiplicative ) + { + if ( !Expr.Op ) { + return cons abs_expr [Expr.factor] + } + else { + return cons abs_expr [ + abs_multiplicative( Expr._multiplicative ) + @Expr.Op + Expr.factor + ] + } + } + + abs_expr abs_additive( Expr: indep::additive ) + { + if ( !Expr.Op ) { + return cons abs_expr [ + abs_multiplicative( Expr.multiplicative ) + ] + } + else { + return cons abs_expr [ + abs_additive( Expr._additive ) + @Expr.Op + abs_multiplicative( Expr.multiplicative ) + ] + } + } + + abs_expr abs_comparative( Expr: indep::comparative ) + { + if ( !Expr.Op ) { + return cons abs_expr [ + abs_additive( Expr.additive ) + ] + } + else { + return cons abs_expr [ + abs_comparative( Expr._comparative ) + @Expr.Op + abs_additive( Expr.additive ) + ] + } + } + + def multiplicative + [multiplicative Op: mult_op factor] + | [factor] + + def additive + [additive Op: add_op multiplicative] + | [multiplicative] + + def comparative + [comparative Op: cmp_op additive] + | [additive] + + def abs_expr + [E1: abs_expr Op: abs_op E2: abs_expr] + | [factor] + + def expr + [comparative] + + def type + [`int] + | [`bool] + | [`char] + | [`ptr] + | [`byte] + + def opt_arr + [`[ expr `]] + | [] + + def var_decl + [type tk_ident opt_arr `;] + + def opt_sub + [ `[ expr `] ] + | [] + + def expr_stmt + [tk_ident opt_sub `= expr `;] + | [expr `;] + + def if_stmt + [`if `( expr `) `{ stmt* `} opt_else] + + def opt_else + [`else `{ stmt* `}] + | [] + + def print_stmt + [`print_int expr `;] + | [`print_buf expr `, expr `;] + | [`print_str expr `;] + | [`print_token `;] + + def ragel_stmt + [`fgoto tk_ident `;] + | [`fcall tk_ident `;] + | [`fncall tk_ident `;] + | [`fnext tk_ident `;] + | [`fgoto `* expr `;] + | [`fcall `* expr `;] + | [`fncall `* expr `;] + | [`fnext `* expr `;] + | [`fexec expr `;] + | [`fhold `;] + | [`fbreak `;] + | [`fnbreak `;] + | [`fret `;] + | [`fnret `;] + + def buf_stmt + [`buf_append `( `) `;] + | [`buf_clear `( `) `;] + + def stmt + [var_decl] + | [expr_stmt] + | [if_stmt] + | [print_stmt] + | [buf_stmt] + | [ragel_stmt] + + def action_block + [`{ stmt* `}] + | [`{ expr `}] + + def section + [`%%{ ragel::ragel_start `}%%] + + def start + [ + test_header + Init: stmt* + section + sect_INPUT + input + sect_OUTPUT + output + ] +end + +namespace out_code + lex + token line + /[^\n]* '\n'/ + end + + def lines + [line*] + + alias line_parser + parser +end + +global Out: parser + +include 'trans-c.lm' +include 'trans-asm.lm' +include 'trans-d.lm' +include 'trans-csharp.lm' +include 'trans-go.lm' +include 'trans-java.lm' +include 'trans-ruby.lm' +include 'trans-ocaml.lm' +include 'trans-rust.lm' +include 'trans-julia.lm' +include 'trans-crack.lm' + +str argvPop() +{ + AE: list_el = argv->pop_el() + return AE->value +} + +Lang: str = argvPop() +OutputFile: str = argvPop() +InputFile: str = argvPop() +global ClassName: str = argvPop() + +Input: stream = open( InputFile, "r" ) +Output: stream = open( OutputFile, "w" ) + +global RagelTree: indep::start = parse indep::start[ Input ] + +if ( !RagelTree ) { + print( error, '\n' ) + exit(1) +} + +# Find the machine name. +global MachineName: ragel::machine_name = ragel::machine_name in RagelTree + +global NeedsEof: bool = false +global ProhibitGenflags: str +for CommDef: indep::comm_def in RagelTree { + switch CommDef + case "@NEEDS_EOF: yes\n" + { + NeedsEof = true + } + case "@PROHIBIT_GENFLAGS:[CV: comm_val]" + { + ProhibitGenflags = $CV + } +} + +if ( Lang == 'c' ) + rw_c( Output ) +elsif ( Lang == 'asm' ) + rw_asm( Output ) +elsif ( Lang == 'd' ) + rw_d( Output ) +elsif ( Lang == 'cs' ) + rw_csharp( Output ) +elsif ( Lang == 'go' ) + rw_go( Output ) +elsif ( Lang == 'java' ) + rw_java( Output ) +elsif ( Lang == 'ruby' ) + rw_ruby( Output ) +elsif ( Lang == 'ocaml' ) + rw_ocaml( Output ) +elsif ( Lang == 'rust' ) + trans_rust::rust( Output ) +elsif ( Lang == 'julia' ) + trans_julia::julia( Output ) +elsif ( Lang == 'crack' ) + trans_crack::crack( Output ) +else { + print( 'trans: unrecognized language: ', Lang, '\n' ) +} -- cgit v1.2.1