From e263920a0216e81f20294fcd6a827fa6b91dd866 Mon Sep 17 00:00:00 2001 From: Oscar Nydza Date: Fri, 5 Apr 2024 11:38:23 +0200 Subject: [PATCH 1/3] Adds initial partest.q file and testing notebook --- test/partest.ipynb | 341 +++++++++++++++++++++++++++++++++++++++++++++ test/partest.q | 9 ++ 2 files changed, 350 insertions(+) create mode 100644 test/partest.ipynb create mode 100644 test/partest.q diff --git a/test/partest.ipynb b/test/partest.ipynb new file mode 100644 index 0000000..b201d40 --- /dev/null +++ b/test/partest.ipynb @@ -0,0 +1,341 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "ec4cacce-8d3d-44ae-8f5b-75c7234ecd57", + "metadata": {}, + "outputs": [ + { + "ename": "\u001b[0;31m../querqus.q. OS reports: No such file or directory\u001b[0m", + "evalue": "\u001b[0;31m../querqus.q. OS reports: No such file or directory\u001b[0m", + "output_type": "error", + "traceback": [ + "\u001b[0;31mevaluation error:\n\u001b[0m", + "\u001b[0;31m../querqus.q. OS reports: No such file or directory\u001b[0m", + "\u001b[0;31m\u001b[0m", + "\u001b[0;31m [0] \\l ../querqus.q\n ^\n\u001b[0m" + ] + } + ], + "source": [ + "\\l ../querqus.q" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "edfeae9b-a526-4b64-b934-1c54630bf381", + "metadata": {}, + "outputs": [], + "source": [ + "/ quercus: parser combinators for q\n", + "\\d .qu\n", + "\n", + "ret:{enlist(x;y)};\n", + "bind:{raze({(a;s):y;x[a]s}[x]')y@};\n", + "map:{bind[(ret x::)]};\n", + "trav:{({bind[{map[{raze(x;y)}[y]][x]}[y]]x}/)(x')y};\n", + "seqA:trav[::];\n", + "zero:{[x]()};\n", + "plus:{x[z],y z};\n", + "fil:{bind[{(zero;ret y)x y}[x]][y]};\n", + "opt:{plus[x;ret()]};\n", + "many:{plus[bind[{map[(enlist[z],)]y x}[x;.z.s];x];ret()]};\n", + "many1:{bind[{map[(enlist[y],)]many x}[x];x]};\n", + "times:{$[x<1;ret();seqA x#y]};\n", + "sep1:{bind[{map[{enlist[x],y}[z]]many seqr[x;y]}[y;x]]x};\n", + "sep:{plus[sep1[x;y];ret()]};\n", + "skip:map zero;\n", + "item:{$[\"\"~x;();enlist(first x;1_ x)]};\n", + "seqf:{bind[{map[{x(y;z)}[x;z]][y]}[x;z]]y};\n", + "seql:seqf[first];seqr:seqf[last];seq:seqf[enlist .];\n", + "sat:{bind[{$[x y;ret y;zero]}[x];item]};\n", + "oneof:{sat in[;x]};\n", + "noneof:{sat(not in[;x]::)};\n", + "between:{seqr[x;seql[z;y]]};\n", + "range:{sat{(x<=z)&z<=y}[x;y]};\n", + "digit:range .\"09\";\n", + "lwr:range .\"az\";\n", + "upr:range .\"AZ\";\n", + "letter:plus[lwr;upr];\n", + "alphanum:plus[letter;digit];\n", + "str:{$[x~count[x]#y;enlist(x;count[x]_y);()]};\n", + "word:many1 letter;\n", + "num:many1 digit;\n", + "chr:{[x:`c]sat[(x=)]};\n", + "spaces:skip many space:chr\" \";\n", + "eof:{$[\"\"~x;ret[()]x;zero x]};\n", + "parens:between[chr\"(\";chr\")\"];\n", + "braces:between[chr\"{\";chr\"}\"];\n", + "c:item;\n", + "j:map[(\"J\"$)]num;\n", + "s:map[(`$)]word;\n", + "\n", + "rparse:{$[()~r:x y;'`parse;1=avg r}" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "43824611-4d0b-4c52-9c43-0df6e02dbc3d", + "metadata": {}, + "outputs": [ + { + "ename": "\u001b[0;31minput\u001b[0m", + "evalue": "\u001b[0;31minput\u001b[0m", + "output_type": "error", + "traceback": [ + "\u001b[0;31mevaluation error:\n\u001b[0m", + "\u001b[0;31minput\u001b[0m", + "\u001b[0;31m\u001b[0m", + "\u001b[0;31m [2] \\t [parser][input]\n ^\n\u001b[0m", + "\u001b[0;31m [1] testtime:{[parser;input;expected;times]\n do[times;r,:(system\"t [parser][input]\")];\n ^\n expected>=avg r}\n\u001b[0m", + "\u001b[0;31m [0] testtime[.qu.times[2;.qu.lwr];\"ab\";1;30]\n ^\n\u001b[0m" + ] + } + ], + "source": [ + "testtime[.qu.times[2;.qu.lwr];\"ab\";1;30]" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "db86fefd-2df9-4852-8ada-536c73f3f07e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0\n" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "/ si se guardan parser e input como globales la celda anterior funciona\n", + "/ quizá los \"fstring\" tiran de variables globales. si es el caso no interesa\n", + "/ habría que buscar una alternativa... (o no)\n", + "parser:.qu.lwr\n", + "input:enlist\"a\"\n", + "\n", + "system\"t [parser][input]\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c00b295-148a-4af9-a18d-a39f9be47e43", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f32e96d-ef18-477d-9bc0-4f071f72b08b", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "9535254e-9172-4876-a612-517e46a5becf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "foo bar baz\n", + "-----------\n", + "3 4 5 \n", + "3 4 5 \n", + "4 4 4 \n" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flip (!). flip((`foo;(3;3;4));\n", + " (`bar;(4;4;4));\n", + " (`baz;(5;5;4)))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "8acbda75-28c2-4c8f-9d88-785858a8268f", + "metadata": {}, + "outputs": [], + "source": [ + "timest:flip(!). flip((`func;`times);\n", + " (`parser;(\".qu.times[2;.qu.digit]\";\".qu.times[3;.qu.digit]\"));\n", + " (`inputs;(\"12\";\"123\"));\n", + " (`expected;(\"12\";\"spare\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "abef91e7-2363-4be4-a52a-2f6c85408346", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "func parser inputs expected\n", + "----------------------------------------------\n", + "times \".qu.times[2;.qu.digit]\" \"12\" \"12\" \n", + "times \".qu.times[3;.qu.digit]\" \"123\" \"spare\" \n" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "timest" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef6b05b5-b62b-45b4-bea2-1b2118edaa2e", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "936e261d-81e4-4397-8b86-b36079cafbba", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"12\" \"\"\n" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "{expected~(eval parse parser)[input]}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2ec3c4b9-62ef-45c8-92ee-a11f82abe649", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Q (kdb+)", + "language": "q", + "name": "qpk" + }, + "language_info": { + "file_extension": ".q", + "mimetype": "text/x-q", + "name": "q", + "version": "4.1.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/test/partest.q b/test/partest.q new file mode 100644 index 0000000..618296d --- /dev/null +++ b/test/partest.q @@ -0,0 +1,9 @@ +\l ../querqus.q; + +test:{z~.[.qu.rparse;(x;y);::]}; +testtime:{[parser;input;expected;times] + do[times;r,:(system"t [parser][input]")]; + expected>=avg r}; + +// begin tests +flip(!).(`func;.qu.ret) \ No newline at end of file From e1b3add2419045f43e403e658478103c2fc1739e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FRANCISCO=20T=C3=93RTOLA=20VIVO?= Date: Wed, 10 Apr 2024 13:32:13 +0200 Subject: [PATCH 2/3] testing script --- test/partest.q | 16 +++++++++++----- test/tests.q | 9 +++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 test/tests.q diff --git a/test/partest.q b/test/partest.q index 618296d..a1ede99 100644 --- a/test/partest.q +++ b/test/partest.q @@ -1,9 +1,15 @@ -\l ../querqus.q; +\l quercus.q +\l test/tests.q test:{z~.[.qu.rparse;(x;y);::]}; testtime:{[parser;input;expected;times] - do[times;r,:(system"t [parser][input]")]; - expected>=avg r}; + system "t ",parser,input} +evaluation:{{test[x;y;z]}' [x[`parser];x[`input];x[`expected]]}; -// begin tests -flip(!).(`func;.qu.ret) \ No newline at end of file +addTests: { + k!{ + (&/)evaluation[v,flip([]parser:{ + op:get[`.qu]x; + $[count[y]>0;op . y;op]}[y;] peach (v:x[y])`args)]}[t;] peach k:1 _ key t:get`.test}; + +tests: ([]function: key s;test: value s:addTests[]) \ No newline at end of file diff --git a/test/tests.q b/test/tests.q new file mode 100644 index 0000000..0693e80 --- /dev/null +++ b/test/tests.q @@ -0,0 +1,9 @@ +// begin tests +\d .test +/f:{{{$[type[x]<0;enlist x;x]} each x} each x}; +times: ([args:((2;.qu.digit);(3;.qu.digit);(2;.qu.lwr)); input: ("12";"1234";"ab"); expected: ("12";"spare";"ab")]); +lwr: ([args:(();());input:(enlist"a";"abc");expected:("a";"spare")]) +many: ([args:(enlist .qu.digit;enlist .qu.lwr;enlist .qu.lwr);input:("123";"abcd";"");expected:("ambig";"ambig";())]) +many1: ([args:enlist(enlist .qu.digit);input:enlist("");expected:enlist("parse")]) +range: ([args: ("25";"ad";"az");input:(enlist"3";enlist "b";enlist "A"); expected:("3";"b";"parse")]) +\d . From 84255bbfb6ce8b85db2b6bbc3991becafb3e38ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?FRANCISCO=20T=C3=93RTOLA=20VIVO?= Date: Fri, 12 Apr 2024 09:20:05 +0200 Subject: [PATCH 3/3] Improvements in testing --- test/partest.q | 6 +++++- test/tests.q | 11 ++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/partest.q b/test/partest.q index a1ede99..a4a69a2 100644 --- a/test/partest.q +++ b/test/partest.q @@ -6,10 +6,14 @@ testtime:{[parser;input;expected;times] system "t ",parser,input} evaluation:{{test[x;y;z]}' [x[`parser];x[`input];x[`expected]]}; +f:{({{$[(type[x]<0) or type[x]>20;enlist x;x]} each x} each `expected _ x), ([expected: x `expected])}; +g:{{$[type[x]=0;x;enlist x]} each x} +h: {$[type[x]=0;`args`input`expected!flip x;x]} addTests: { k!{ + v:f g h x y; (&/)evaluation[v,flip([]parser:{ op:get[`.qu]x; - $[count[y]>0;op . y;op]}[y;] peach (v:x[y])`args)]}[t;] peach k:1 _ key t:get`.test}; + $[count[y]>0;op . y;op]}[y;] peach v `args)]}[t;] peach k:1 _ key t:get`.test}; tests: ([]function: key s;test: value s:addTests[]) \ No newline at end of file diff --git a/test/tests.q b/test/tests.q index 0693e80..70f14f2 100644 --- a/test/tests.q +++ b/test/tests.q @@ -1,9 +1,10 @@ // begin tests \d .test -/f:{{{$[type[x]<0;enlist x;x]} each x} each x}; times: ([args:((2;.qu.digit);(3;.qu.digit);(2;.qu.lwr)); input: ("12";"1234";"ab"); expected: ("12";"spare";"ab")]); -lwr: ([args:(();());input:(enlist"a";"abc");expected:("a";"spare")]) -many: ([args:(enlist .qu.digit;enlist .qu.lwr;enlist .qu.lwr);input:("123";"abcd";"");expected:("ambig";"ambig";())]) -many1: ([args:enlist(enlist .qu.digit);input:enlist("");expected:enlist("parse")]) -range: ([args: ("25";"ad";"az");input:(enlist"3";enlist "b";enlist "A"); expected:("3";"b";"parse")]) +lwr: ([args:(();());input:("a";"abc");expected:("a";"spare")]); +many: ([args:(.qu.digit;.qu.lwr;.qu.lwr);input:("123";"abcd";"");expected:("ambig";"ambig";())]); +many1: ([args:.qu.digit;input: "";expected: "parse"]); +range: ([args: ("25";"ad";"az");input:(enlist "3";enlist "b"; enlist "A"); expected:("3";"b";"parse")]); +word: `args`input`expected!((();();());("hello";"a";"abc1");("ambig";enlist"a";"ambig")); +braces: ((.qu.word;"{hello}";"hello");(.qu.word;"{hello";"parse")) \d .