add parser library documentation

This commit is contained in:
martinbaker 2019-12-28 18:28:36 +00:00
parent 3b443e262f
commit d86f82e836
11 changed files with 2673 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

1154
docs/image/parserModules.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,294 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="topLevel.svg">
<defs
id="defs2">
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker3617"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt;stroke-opacity:1;fill:#0000ff;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path3615" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker2891"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path2889"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt;stroke-opacity:1;fill:#0000ff;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker2049"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path2047"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt;stroke-opacity:1;fill:#0000ff;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker1539"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt;stroke-opacity:1;fill:#0000ff;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1537" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path830"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt;stroke-opacity:1;fill:#0000ff;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="396.85039"
inkscape:cy="560"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect815"
width="35.983334"
height="18.25625"
x="37.306248"
y="79.512497"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<rect
y="79.512497"
x="92.339577"
height="18.25625"
width="35.983334"
id="rect817"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
style="fill:none;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 73.554166,88.508337 16.66875,-0.26459"
id="path819"
inkscape:connector-curvature="0"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
inkscape:connector-curvature="0"
id="path1535"
d="m 18.785416,88.77292 16.66875,-0.26459"
style="fill:none;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1539)"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
style="fill:none;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker2049)"
d="m 128.32291,88.243753 16.66875,-0.26459"
id="path2045"
inkscape:connector-curvature="0"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="20.372915"
y="85.597931"
id="text2857"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan2855"
x="20.372915"
y="85.597931"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332">String</tspan></text>
<text
id="text2861"
y="80.835434"
x="76.199997"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332"
y="80.835434"
x="76.199997"
sodipodi:role="line"
id="tspan2867">List</tspan><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332"
y="86.127098"
x="76.199997"
sodipodi:role="line"
id="tspan2871">Token</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="130.96875"
y="85.068764"
id="text2865"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan2863"
x="130.96875"
y="85.068764"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332">PTerm</tspan></text>
<text
id="text2875"
y="89.302101"
x="47.360416"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:0.26458332;"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332;fill:#0000ff;"
y="89.302101"
x="47.360416"
id="tspan2873"
sodipodi:role="line">Lexer</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="100.27708"
y="89.037521"
id="text2879"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan2877"
x="100.27708"
y="89.037521"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#0000ff;stroke-width:0.26458332">Parser</tspan></text>
<path
style="fill:none;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker2891)"
d="m 52.916666,71.575003 v 7.67291"
id="path2887"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3613"
d="m 108.74375,71.575003 v 7.67291"
style="fill:none;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker3617)"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text4173"
y="69.987518"
x="43.391666"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332"
y="69.987518"
x="43.391666"
id="tspan4171"
sodipodi:role="line">Recogniser</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="97.102081"
y="69.722939"
id="text4177"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan4175"
x="97.102081"
y="69.722939"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332">Grammar</tspan></text>
<text
inkscape:export-ydpi="61.120499"
inkscape:export-xdpi="61.120499"
id="text854"
y="93.800011"
x="131.23334"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.26458332"
y="103.5316"
x="131.23334"
id="tspan852"
sodipodi:role="line" /></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/image/tokenise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

740
docs/image/tokenise.svg Normal file
View File

@ -0,0 +1,740 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="tokenise.svg">
<defs
id="defs2">
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker7119"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path7117" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker4031"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path4029"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker1931"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1929" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path1036"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="497.48698"
inkscape:cy="885.5"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect815"
width="4.3310161"
height="4.3471913"
x="61.383358"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="62.917812"
y="55.649193"
id="text819"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan817"
x="62.917812"
y="55.649193"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">i</tspan></text>
<rect
y="51.995804"
x="65.714371"
height="4.3471913"
width="4.3310161"
id="rect823"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text827"
y="55.307304"
x="66.760414"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="55.307304"
x="66.760414"
id="tspan825"
sodipodi:role="line">n</tspan></text>
<rect
y="51.995804"
x="70.045387"
height="4.3471913"
width="4.3310161"
id="rect829"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text833"
y="55.063095"
x="71.237953"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="55.063095"
x="71.237953"
id="tspan831"
sodipodi:role="line">p</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect835"
width="4.3310161"
height="4.3471913"
x="74.376404"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="75.422447"
y="55.356148"
id="text839"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan837"
x="75.422447"
y="55.356148"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">u</tspan></text>
<rect
y="51.995804"
x="78.70742"
height="4.3471913"
width="4.3310161"
id="rect841"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text845"
y="55.649193"
x="80.241875"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="55.649193"
x="80.241875"
id="tspan843"
sodipodi:role="line">t</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect847"
width="4.3310161"
height="4.3471913"
x="83.038437"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="59.172871"
y="88.457558"
id="text851"><tspan
sodipodi:role="line"
id="tspan849"
x="59.172871"
y="92.350197"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none" /></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect853"
width="4.3310161"
height="4.3471913"
x="87.369453"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="88.46434"
y="55.453827"
id="text857"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan855"
x="88.46434"
y="55.453827"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">s</tspan></text>
<rect
y="51.995804"
x="91.70047"
height="4.3471913"
width="4.3310161"
id="rect859"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text863"
y="55.649193"
x="93.234924"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="55.649193"
x="93.234924"
id="tspan861"
sodipodi:role="line">t</tspan></text>
<rect
y="51.995804"
x="96.031487"
height="4.3471913"
width="4.3310161"
id="rect865"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text869"
y="55.649193"
x="97.565941"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="55.649193"
x="97.565941"
id="tspan867"
sodipodi:role="line">r</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect871"
width="4.3310161"
height="4.3471913"
x="100.3625"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="101.89697"
y="55.649193"
id="text875"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan873"
x="101.89697"
y="55.649193"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">i</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect877"
width="4.3310161"
height="4.3471913"
x="104.69353"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="105.73955"
y="55.50267"
id="text881"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan879"
x="105.73955"
y="55.50267"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">n</tspan></text>
<rect
y="51.995804"
x="109.0245"
height="4.3471913"
width="4.3310161"
id="rect883"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text887"
y="54.965416"
x="110.21709"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="54.965416"
x="110.21709"
id="tspan885"
sodipodi:role="line">g</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="125.67681"
y="55.359386"
id="text893"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan891"
x="125.67681"
y="55.359386"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">:String</tspan></text>
<rect
y="51.995804"
x="113.35551"
height="4.3471913"
width="4.3310161"
id="rect895"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text899"
y="55.50267"
x="114.40154"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="59.395306"
x="114.40154"
id="tspan897"
sodipodi:role="line" /></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect901"
width="4.3310161"
height="4.3471913"
x="117.68649"
y="51.995804"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="118.87907"
y="55.494583"
id="text905"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan903"
x="118.87907"
y="55.494583"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">1</tspan></text>
<g
id="g950"
transform="translate(-15.319488,0.319156)"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499">
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect907"
width="11.990757"
height="4.3471909"
x="47.978806"
y="69.310013" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="48.706326"
y="72.963402"
id="text911"><tspan
sodipodi:role="line"
id="tspan909"
x="48.706326"
y="72.963402"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">token</tspan></text>
<rect
y="69.310013"
x="59.969563"
height="4.2674026"
width="10.075821"
id="rect913"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text917"
y="72.940666"
x="61.015606"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="72.940666"
x="61.015606"
id="tspan915"
sodipodi:role="line">line</tspan></text>
<rect
y="69.389801"
x="70.045387"
height="4.1876144"
width="7.5225825"
id="rect919"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text923"
y="72.935829"
x="70.998589"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="72.935829"
x="70.998589"
id="tspan921"
sodipodi:role="line">col</tspan></text>
</g>
<text
id="text927"
y="80.971657"
x="40.541954"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:4.23333311px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="80.971657"
x="40.541954"
sodipodi:role="line"
id="tspan933">:(List (TokenData Token), Int, Int, String)</tspan></text>
<g
id="g970"
transform="translate(16.596112,0.319156)"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499">
<rect
y="69.310013"
x="47.978806"
height="4.3471909"
width="11.990757"
id="rect952"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text956"
y="72.963402"
x="48.706326"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="72.963402"
x="48.706326"
id="tspan954"
sodipodi:role="line">token</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect958"
width="10.075821"
height="4.2674026"
x="59.969563"
y="69.310013" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="61.015606"
y="72.940666"
id="text962"><tspan
sodipodi:role="line"
id="tspan960"
x="61.015606"
y="72.940666"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">line</tspan></text>
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect964"
width="7.5225825"
height="4.1876144"
x="70.045387"
y="69.389801" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="70.998589"
y="72.935829"
id="text968"><tspan
sodipodi:role="line"
id="tspan966"
x="70.998589"
y="72.935829"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">col</tspan></text>
</g>
<g
transform="translate(48.591501,0.319156)"
id="g990"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499">
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect972"
width="11.990757"
height="4.3471909"
x="47.978806"
y="69.310013" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="48.706326"
y="72.963402"
id="text976"><tspan
sodipodi:role="line"
id="tspan974"
x="48.706326"
y="72.963402"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">token</tspan></text>
<rect
y="69.310013"
x="59.969563"
height="4.2674026"
width="10.075821"
id="rect978"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text982"
y="72.940666"
x="61.015606"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="72.940666"
x="61.015606"
id="tspan980"
sodipodi:role="line">line</tspan></text>
<rect
y="69.389801"
x="70.045387"
height="4.1876144"
width="7.5225825"
id="rect984"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
id="text988"
y="72.935829"
x="70.998589"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="72.935829"
x="70.998589"
id="tspan986"
sodipodi:role="line">col</tspan></text>
</g>
<path
style="fill:none;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 125.97308,68.549658 1.30238,0.0089 -0.0153,6.481345 h -1.30803"
id="path992"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path994"
d="m 32.561899,68.619523 -1.30238,0.0089 0.0153,6.481345 h 1.30803"
style="fill:none;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<rect
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect996"
width="11.990757"
height="4.3471909"
x="155.60759"
y="69.899559"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
x="156.33508"
y="73.552948"
id="text1000"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
sodipodi:role="line"
id="tspan998"
x="156.33508"
y="73.552948"
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none">string</tspan></text>
<rect
y="69.750786"
x="130.3979"
height="4.2674026"
width="10.075821"
id="rect1002"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text1006"
y="73.381439"
x="131.44394"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="73.381439"
x="131.44394"
id="tspan1004"
sodipodi:role="line">line</tspan></text>
<rect
y="69.830574"
x="143.64868"
height="4.1876144"
width="7.5225825"
id="rect1008"
style="opacity:1;vector-effect:none;fill:none;fill-opacity:0.97596154;fill-rule:evenodd;stroke:#ff0000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<text
id="text1012"
y="73.376602"
x="144.60188"
style="font-style:normal;font-weight:normal;font-size:4.23333311px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499"><tspan
style="font-size:4.23333311px;stroke-width:0.70555556;stroke-miterlimit:4;stroke-dasharray:none"
y="73.376602"
x="144.60188"
id="tspan1010"
sodipodi:role="line">col</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 58.415342,69.700595 -0.143613,-5.887785 4.912582,-0.06048 0.03784,-6.371998"
id="path1025"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
inkscape:connector-curvature="0"
id="path1927"
d="m 89.918872,69.996556 -0.02264,-12.07186"
style="fill:none;stroke:#000000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker1931)"
sodipodi:nodetypes="cc"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
sodipodi:nodetypes="cccc"
style="fill:none;stroke:#000000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4031)"
d="m 122.08751,69.519138 -0.0832,-5.464386 -2.3456,-0.06048 -0.20406,-6.674425"
id="path4027"
inkscape:connector-curvature="0"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
<path
inkscape:connector-curvature="0"
id="path7115"
d="m 147.18896,69.882051 -0.0832,-5.827299 -22.72919,0 -0.446,-6.251027"
style="fill:none;stroke:#000000;stroke-width:0.70555556;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker7119)"
sodipodi:nodetypes="cccc"
inkscape:export-xdpi="61.120499"
inkscape:export-ydpi="61.120499" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -25,5 +25,6 @@ Documentation for the Idris Language
effects/index
proofs/index
elaboratorReflection/index
parserLibrary/index
reference/index
guides/index

View File

@ -0,0 +1,23 @@
.. _parserLibrary:
########################
Lexer and Parser Library
########################
A tutorial on the lexer and parser library in Idris.
.. note::
The documentation for Idris has been published under the Creative
Commons CC0 License. As such to the extent possible under law, *The
Idris Community* has waived all copyright and related or neighboring
rights to Documentation for Idris.
More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
.. toctree::
:maxdepth: 1
introduction
lexer
parser

View File

@ -0,0 +1,209 @@
.. _parserLibrary:
***************************
Parser Library Introduction
***************************
The Idris elaborator is responsible for converting high-level Idris code into the core language.
It is implemented as a kind of embedded tactic language in Haskell, where tactic scripts are written in an *elaboration monad* that provides error handling and a proof state.
For details, see `Edwin Brady's 2013 paper in the Journal of Functional
Programming <https://eb.host.cs.st-andrews.ac.uk/drafts/impldtp.pdf>`_.
Elaborator reflection makes the elaboration type as well as a selection of its tactics available to Idris code.
This means that metaprograms written in Idris can have complete control over the elaboration process, generating arbitrary code, and they have access to all of the facilities available in the elaborator, such as higher-order unification, type checking, and emitting auxiliary definitions.
The Elaborator State
====================
The elaborator state contains information about the ongoing elaboration process.
In particular, it contains a *goal type*, which is to be filled by an under-construction *proof term*.
The proof term can contain *holes*, each of which has a scope in which it is valid and a type.
Some holes may additionally contain *guesses*, which can be substituted in the scope of the hole.
The holes are tracked in a *hole queue*, and one of them is *focused*.
In addition to the goal type, proof term, and holes, the elaborator state contains a collection of unsolved unification problems that can affect elaboration.
The elaborator state is not directly available to Idris programs.
Instead, it is modified through the use of *tactics*, which are operations that affect the elaborator state.
A tactic that returns a value of type ``a``, potentially modifying the elaborator state, has type ``Elab a``.
The default tactics are all in the namespace ``Language.Reflection.Elab.Tactics``.
Running Elaborator Scripts
==========================
On their own, tactics have no effect.
The meta-operation ``%runElab script`` runs ``script`` in the current elaboration context.
Before you can use ``%runElab``, you will have to enable the language extension by adding
``%language ElabReflection`` in your file (or by passing ``-X ElabReflection`` to the
``idris`` executable from your command line).
For example, the following script constructs the identity function at type ``Nat``:
.. code-block:: idris
idNat : Nat -> Nat
idNat = %runElab (do intro `{{x}}
fill (Var `{{x}})
solve)
On the right-hand side, the Idris elaborator has the goal ``Nat -> Nat``.
When it encounters the ``%runElab`` directive, it fulfills this goal by running the provided script.
The first tactic, ``intro``, constructs a lambda that binds the name ``x``.
The name argument is optional because a default name can be taken from the function type.
Now, the proof term is of the form ``\x : Nat => {hole}``.
The second tactic, ``fill``, fills this hole with a guess, giving the term ``\x : Nat => {hole≈x}``.
Finally, the ``solve`` tactic instantiates the guess, giving the result ``\x : Nat => x``.
Because elaborator scripts are ordinary Idris expressions, it is also possible to use them in multiple contexts.
Note that there is nothing ``Nat``-specific about the above script.
We can generate identity functions at any concrete type using the same script:
.. code-block:: idris
mkId : Elab ()
mkId = do intro `{{x}}
fill (Var `{{x}})
solve
idNat : Nat -> Nat
idNat = %runElab mkId
idUnit : () -> ()
idUnit = %runElab mkId
idString : String -> String
idString = %runElab mkId
Interactively Building Elab Scripts
===================================
You can build an ``Elab`` script interactively at the REPL.
Use the command ``:metavars``, or ``:m`` for short, to list the available holes.
Then, issue the ``:elab <hole>`` command at the REPL
to enter the elaboration shell.
At the shell, you can enter proof tactics to alter the proof state.
You can view the system-provided tactics prior to entering the shell
by issuing the REPL command ``:browse Language.Reflection.Elab.Tactics``.
When you have discharged all goals, you can complete the proof
using the ``:qed`` command and receive in return an elaboration script
that fills the hole.
The interactive elaboration shell accepts a limited number of commands,
including a subset of the commands understood by the normal Idris REPL
as well as some elaboration-specific commands. It also supports the
``do``-syntax, meaning you can write ``res <- command`` to bind the result of
``command`` to variable ``res``.
General-purpose commands:
- ``:eval <EXPR>``, or ``:e <EXPR>`` for short, evaluates the provided expression
and prints the result.
- ``:type <EXPR>``, or ``:t <EXPR>`` for short, prints the provided expression
together with its type.
- ``:search <TYPE>`` searches for definitions having the provided type.
- ``:doc <NAME>`` searches for definitions with the provided name and prints their
documentation.
Commands for viewing the proof state:
- ``:state`` displays the current state of the term being constructed. It lists both
other goals and the current goal.
- ``:term`` displays the current proof term as well as its yet-to-be-filled holes.
Commands for manipulating the proof state:
- ``:undo`` undoes the effects of the last tactic.
- ``:abandon`` gives up on proving the current lemma and quits the elaboration shell.
- ``:qed`` finishes the script and exits the elaboration shell. The shell will only accept
this command once it reports, "No more goals." On exit, it will print out the finished
elaboration script for you to copy into your program.
Failure
=======
Some tactics may *fail*.
For example, ``intro`` will fail if the focused hole does not have a function type, ``solve`` will fail if the current hole does not contain a guess, and ``fill`` will fail if the term to be filled in has the wrong type.
Scripts can also fail explicitly using the ``fail`` tactic.
To account for failure, there is an ``Alternative`` implementation for ``Elab``.
The ``<|>`` operator first tries the script to its left.
If that script fails, any changes that it made to the state are undone and the right argument is executed.
If the first argument succeeds, then the second argument is not executed.
Querying the Elaboration State
==============================
``Elab`` includes operations to query the elaboration state, allowing scripts to use information about their environment to steer the elaboration process.
The ordinary Idris bind syntax can be used to propagate this information.
For example, a tactic that solves the current goal when it is the unit type might look like this:
.. code-block:: idris
triv : Elab ()
triv = do compute
g <- getGoal
case (snd g) of
`(() : Type) => do fill `(() : ())
solve
otherGoal => fail [ TermPart otherGoal
, TextPart "is not trivial"
]
The tactic ``compute`` normalises the type of its goal with respect to the current context.
While not strictly necessary, this allows ``triv`` to be used in contexts where the triviality of the goal is not immediately apparent.
Then, ``getGoal`` is used, and its result is bound to ``g``.
Because it returns a pair consisting of the current goal's name and type, we case-split on its second projection.
If the goal type turns out to have been the unit type, we fill using the unit constructor and solve the goal.
Otherwise, we fail with an error message informing the user that the current goal is not trivial.
Additionally, the elaboration state can be dumped into an error message with the ``debug`` tactic.
A variant, ``debugMessage``, allows arbitrary messages to be included with the state, allowing for a kind of "``printf`` debugging" of elaboration scripts.
The message format used by ``debugMessage`` is the same for errors produced by the error reflection mechanism, allowing the re-use of the Idris pretty-printer when rendering messages.
Changing the Global Context
===========================
``Elab`` scripts can modify the global context during execution.
Just as the Idris elaborator produces auxiliary definitions to implement features such as ``where``-blocks and ``case`` expressions, user elaboration scripts may need to define functions.
Furthermore, this allows ``Elab`` reflection to be used to implement features such as interface deriving.
The operations ``declareType``, ``defineFunction``, and ``addImplementation`` allow ``Elab`` scripts to modify the global context.
Using Idris's Features
======================
The Idris compiler has a number of ways to automate the construction of terms.
On its own, the ``Elab`` state and its interactions with the unifier allow implicits to be solved using unification.
Additional operations use further features of Idris.
In particular, ``resolveTC`` solves the current goal using interface resolution, ``search`` invokes the proof search mechanism, and ``sourceLocation`` finds the context in the original file at which the elaboration script is invoked.
Recursive Elaboration
=====================
The elaboration mechanism can be invoked recursively using the ``runElab`` tactic.
This tactic takes a goal type and an elaboration script as arguments and runs the script in a fresh lexical environment to create an inhabitant of the provided goal type.
This is primarily useful for code generation, particularly for generating pattern-matching clauses, where variable scope needs to be one that isn't the present local context.
Learn More
==========
Some tactics are introduced in the :ref:`proofs-index` section with further details, of those most relevant to elaborator reflection, on the following pages.
The list of built-in tactics can be obtained using the ``:browse`` command in an Idris REPL or the corresponding feature in one of the graphical IDE clients to explore the ``Language.Reflection.Elab.Tactics`` namespace.
All of the built-in tactics contain documentation strings.
For alternative ways to extend the Idris language see the :ref:`reference-index` section.
The following pages explain more about the theory and practice of elaborator reflection.

View File

@ -0,0 +1,60 @@
Lexer
=====
Idris provides a mechanism to modify the language without having to recompile Idris itself. We can think of this in terms of metaprogramming or domain specific languages or just building in new capabilities.
In order to extend the language we need to know something about how Idris is compiled. This page explains only what is needed to customise the elaboration. For more information about the compiler's implementation see `Edwin Brady's 2013 paper`_ and for customising the elaboration process see `Elaborator reflection: extending Idris in Idris`_ and `David Christiansen's PhD thesis`_.
Compilation of Idris proceeds through a number of stages.
- First, Idris is desugared by inserting placeholders for terms to be guessed by the compiler and replacing certain syntactic forms, such as do-notation, with the functions that implement them.
- Then, this desugared Idris is translated into a much simpler core language, called TT. This translation process is called elaboration.
- Finally, TT is type checked a second time to rule out errors, and then compiled into the target language.
.. image:: ../image/idrisTopLevel.png
:width: 484px
:height: 147px
:alt: diagram illustrating these stages of Idris compilation
TT is a core language which is syntactically very simple. This makes it easy for computers to process but very verbose and hard for humans to read. The Idris elaborator is written in Haskell using an elaboration library that was inspired by the tactics in interactive proof assistants such as Coq.
.. list-table::
* - There are some similarities with a proof assistant but in Idris the elaborator is an interpreter of Idris source in the elaboration monad, where each syntactic construct of Idris is interpreted as a sequence of tactics.
- .. image:: ../image/compareToProofAssist.png
:width: 206px
:height: 112px
:alt: diagram comparing elaboration with proof assistant
The primitives in the elaboration library are not just useful for the implementors of Idris itself. They can also be used by authors of extensions to the compiler, using a mechanism known as elaborator reflection.
During elaboration TT (Raw) structure contains:
- holes - placeholders for terms that have not yet been filled in.
- guesses - similar to let bindings, except with no reduction rule, so that elaboration programs can control the precise shape of terms that are under construction.
For more information about holes and guesses see `Dependently Typed Functional Programs and their Proofs by McBride 1999`_.
The following diagram is intended to illustrate a high level view of the tactics and how this eventually results in the TT language being generated. It is not necessary to understand the details at this stage. The intention is to help build up some intuition so that, when we get into the details, we can recognise how this fits into the big picture.
.. image:: ../image/elabOverview.png
:width: 410px
:height: 282px
:alt: diagram illustrating overview of TT language being generated from tactics.
As already mentioned the TT core language is kept syntactically very simple, for instance, here are the binders in TT with corresponding code and logic type validity rules:
.. list-table::
* - This diagram illustrates the basis of the compilation process in logic (in this case for binders). It is not necessary to be an expert logician to understand elaborator reflection. However, when learning about tactics, they may appear arbitrary without knowing some theory. For more information about this see `Edwin Brady's 2013 paper`_.
- .. image:: ../image/binders.png
:width: 310px
:height: 203px
:alt: diagram illustrating basis of code in logic
.. target-notes::
.. _`Edwin Brady's 2013 paper`: https://eb.host.cs.st-andrews.ac.uk/drafts/impldtp.pdf
.. _`Elaborator reflection: extending Idris in Idris`: https://dl.acm.org/citation.cfm?doid=2951913.2951932
.. _`David Christiansen's PhD thesis`: https://davidchristiansen.dk/david-christiansen-phd.pdf
.. _`Dependently Typed Functional Programs and their Proofs by McBride 1999`: https://www.era.lib.ed.ac.uk/handle/1842/374

View File

@ -0,0 +1,192 @@
Elaborator Reflection - Identity Example
========================================
.. list-table::
* - This example of elaborator reflection steps through this metaprogram that generates the identity function:
- .. code-block:: idris
%language ElabReflection
idNat : Nat -> Nat
idNat = %runElab (do intro `{{x}}
fill (Var `{{x}})
solve)
.. list-table::
:widths: 200 100
* - At the beginning of executing the elaboration script, the initial state consists of a single hole of type Nat -> Nat.
As a first approximation, the state consists of a term with holes in it, an indicator of which hole is focused, a queue of the next holes to focus on, and miscellaneous information like a source of fresh names. The intro tactic modifies this state, replacing the focused hole with a lambda and focusing on the lambda's body.
- .. image:: ../image/tree.png
:width: 119px
:height: 109px
The following is a walkthough looking at the state after each tactic:
.. list-table::
* - Start with the type signature like this:
- .. code-block:: idris
%language ElabReflection
idNat : Nat -> Nat
idNat = %runElab (do
* - In order to investigate how the program works this table shows the proof state at each stage as the tactics are applied. So here is the proof state at the start:
- .. image:: ../image/elabProofStateEx1_1.png
:width: 310px
:height: 115px
* - This table shows the hole types and what they depend on. The aim is to illustrate the types by analogy with proofs, as a line with the premises above it and the conclusion below it.
- .. image:: ../image/elabLogicEx1_1.png
:width: 277px
:height: 15px
* - The term is:
- ?{hole_0} ≈ ? {hole_2} . {hole_2} . {hole_0}
* - It is possible to read the state from the script by calling getEnv, getGoal and getHoles.
- The output of these calls contain structures with TT code. To show the results I hacked this: `my code`_. TT code is not really designed to be readable by humans, all the names are fully expanded, everything has a type down to universes (type of types). This is shown here to illustrate the information available.
.. code-block:: idris
getEnv=[]
getGoal=(hole_2, __pi_arg:(Nat.["Nat", "Prelude"]:{
type constructor tag=8 number=0}.Type:U=(20:./Prelude/Nat.idr)->.
{name ref{type constructor tag=8 number=0}Nat.["Nat","Prelude"]:
Type:U=(20:./Prelude/Nat.idr)
})
})
getHoles=[{hole_2},{hole_0}]
* - getGuess
- error no guess
* - Introduce a lambda binding around the current hole and focus on the body.
- intro \`{{x}}
* - The state now looks like this:
- .. image:: ../image/elabProofStateEx1_2.png
:width: 312px
:height: 84px
* - The hole types now looks like this:
- .. image:: ../image/elabLogicEx1_2.png
:width: 279px
:height: 26px
* - The term now looks like this:
- ?{hole_0} ≈ λ x . ? {hole_2} . {hole_2} . {hole_0}
* - Again we can check the state by calling getEnv, getGoal and getHoles: see `my code`_
- .. code-block:: idris
getEnv=[(x, {λ (Nat.["Nat", "Prelude"]:{
type constructor tag=8 number=0}).
Type:U=(20:./Prelude/Nat.idr)
})]
getGoal=(hole_2, {name ref{type constructor tag=8 number=0}
Nat.["Nat","Prelude"]:Type:U=(20:./Prelude/Nat.idr)
})
getHoles=[{hole_2},{hole_0}]
* - getGuess
- error no guess
* - Place a term into a hole, unifying its type
- fill (Var \`{{x}})
* - The state still looks like this:
- .. image:: ../image/elabProofStateEx1_3.png
:width: 312px
:height: 57px
* - The hole types now looks like this:
- .. image:: ../image/elabLogicEx1_3.png
:width: 290px
:height: 26px
* - The term now looks like this:
- ?{hole_0} ≈ λ x . ?{hole_2} ≈ x . {hole_2} . {hole_0}
* - Again we can check the state by calling getEnv, getGoal and getHoles: see `my code`_
- .. code-block:: idris
getEnv=[(x, {λ (Nat.["Nat", "Prelude"]:
{type constructor tag=8 number=0}).
Type:U=(20:./Prelude/Nat.idr)
})]
getGoal=(hole_2, {name ref{type constructor tag=8 number=0}
Nat.["Nat","Prelude"]:Type:U=(20:./Prelude/Nat.idr)
})
getHoles=[{hole_2}, {hole_0}]
* - getGuess
- .. code-block:: idris
{name ref bound x:
{name ref{type constructor tag=8 number=0}
Nat.["Nat","Prelude"]:Type:U=(20:./Prelude/Nat.idr)
}
}
* - Substitute a guess into a hole.
- solve
* - The hole types now looks like this:
- .. image:: ../image/elabLogicEx1_4.png
:width: 131px
:height: 14px
* - The term now looks like this:
- ?{hole_0} ≈ λ x . x . {hole_0}
* - getEnv
getGoal
getHoles
- .. code-block:: idris
getEnv=[]
getGoal=(hole_0, __pi_arg:(Nat.["Nat", "Prelude"]:{
type constructor tag=8 number=0}.
Type:U=(20:./Prelude/Nat.idr)
->.{name ref
{type constructor tag=8 number=0}
Nat.["Nat","Prelude"]:Type:U=(20:./Prelude/Nat.idr)
})
})
getHoles=[{hole_0}]
* - getGuess
- .. code-block:: idris
x:({λ (Nat.["Nat", "Prelude"]:{
type constructor tag=8 number=0}).
Type:U=(20:./Prelude/Nat.idr)
}.{
name ref bound
x:{name ref {type constructor tag=8 number=0}
Nat.["Nat","Prelude"]:Type:U=(20:./Prelude/Nat.idr)
}
})
}
.. target-notes::
.. _`my code`: https://github.com/martinbaker/Idris-dev/blob/uglyTTPrinter/libs/prelude/Language/Reflection/TTPrinter.idr