blob: a3220f1067737c4a414e9a5598aab8099a8723ce [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.12">
<meta name="author" content="Copyright (c) 2010, 2021 Contributors to the Eclipse Foundation">
<title>SeText documentation (Incubation)</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment @import statement to use as custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
abbr[title]{border-bottom:1px dotted}
b,strong{font-weight:bold}
dfn{font-style:italic}
hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
ul.square{list-style-type:square}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
abbr{text-transform:none}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
blockquote cite::before{content:"\2014 \0020"}
blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em}
pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em}
pre.pygments .lineno::before{content:"";margin-right:-.125em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
ul.checklist{margin-left:.625em}
ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em}
ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
.gist .file-data>table td.line-data{width:99%}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:50%;border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<!--
Copyright (c) 2010, 2021 Contributors to the Eclipse Foundation
See the NOTICE file(s) distributed with this work for additional
information regarding copyright ownership.
This program and the accompanying materials are made available under the terms
of the MIT License which is available at https://opensource.org/licenses/MIT
SPDX-License-Identifier: MIT
-->
<style>
.menu, .submenu, .menuitem, .menuref {
background-color: Menu;
}
.button {
border: 1px solid ButtonFace;
/*
Styling too similar to a real button is considered bad practice, see https://github.com/asciidoctor/asciidoctor/issues/1881#issuecomment-250702085
border: 2px outset ButtonFace;
background-color: ButtonFace;
*/
padding-left: 0.5ex;
padding-right: 0.5ex;
font-weight: normal;
font-family: "Segoe UI","Open Sans","DejaVu Sans",sans-serif;
white-space: nowrap;
}
.button:before {
content: none !important;
}
.button:after {
content: none !important;
}
#footer-text, #footer-text a {
color: rgba(255,255,255,.8)
}
</style>
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>SeText documentation (Incubation)</h1>
<div class="details">
<span id="author" class="author">Copyright (c) 2010, 2021 Contributors to the Eclipse Foundation</span><br>
<span id="revnumber">version v0.2-RC1</span>
</div>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#setext-reference-manual">SeText Reference Manual</a>
<ul class="sectlevel2">
<li><a href="#setext-lexical-syntax">SeText lexical syntax</a></li>
<li><a href="#setext-specifying-lexical-syntax">Specifying lexical syntax using SeText</a></li>
<li><a href="#setext-regular-expressions">Regular expressions</a></li>
<li><a href="#setext-terminal-descriptions">Terminal descriptions</a></li>
<li><a href="#setext-imports">Imports</a></li>
<li><a href="#setext-scanner-hooks">Scanner hooks</a></li>
<li><a href="#setext-specifying-grammars">Specifying grammars using SeText</a></li>
<li><a href="#setext-parser-hooks">Parser hooks</a></li>
<li><a href="#setext-usage-hints">Usage hints</a></li>
<li><a href="#setext-generated-scanners-parsers">Generated scanners/parsers</a></li>
</ul>
</li>
<li><a href="#setext-using-in-an-eclipse-plugin-project">Using SeText in an Eclipse Plug-in Project</a></li>
<li><a href="#setext-limitations-issues">Limitations and issues</a></li>
<li><a href="#setext-release-notes">SeText release notes</a>
<ul class="sectlevel2">
<li><a href="#version-0-2">Version 0.2</a></li>
<li><a href="#version-0-1">Version 0.1</a></li>
</ul>
</li>
<li><a href="#setext-legal">Legal</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>SeText is a textual syntax specification language and associated scanner/parser generator.
It can be used to specify the syntax of a language, and automatically generate a scanner and LALR(1) parser(s).</p>
</div>
<div class="paragraph">
<p>SeText is one of the tools of the Eclipse ESCET&#8482; project.
Visit the <a href="https://eclipse.org/escet">project website</a> for downloads, installation instructions, source code, general tool usage information, information on how to contribute, and more.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The Eclipse ESCET project, including the SeText language and toolset, is currently in the <a href="https://wiki.eclipse.org/Development_Resources/Process_Guidelines/What_is_Incubation">Incubation Phase</a>.</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="./eclipse-incubation.png" alt="eclipse incubation" width="300"></span></p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>For the purpose of this document, it is assumed that the reader is familiar with scanner/parser generators (for example <em>yacc</em>/<em>bison</em> and <em>lex</em>/<em>flex</em>), scanner and LALR(1) parser technology (including regular expressions and BNF notation), and understands the limitations of the LALR(1) algorithm.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You can <a href="eclipse-escet-incubation-setext-manual.pdf">download this manual</a> as a PDF as well.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The following topics are discussed:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#setext-reference-manual">SeText Reference Manual</a></p>
</li>
<li>
<p><a href="#setext-using-in-an-eclipse-plugin-project">Using SeText in an Eclipse Plug-in Project</a></p>
</li>
<li>
<p><a href="#setext-limitations-issues">Limitations and issues</a></p>
</li>
<li>
<p><a href="#setext-release-notes">SeText release notes</a></p>
</li>
<li>
<p><a href="#setext-legal">Legal information</a></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setext-reference-manual">SeText Reference Manual</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This manual explains the SeText language.
Topics discussed here are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#setext-lexical-syntax">SeText lexical syntax</a></p>
</li>
<li>
<p><a href="#setext-specifying-lexical-syntax">Specifying lexical syntax using SeText</a></p>
</li>
<li>
<p><a href="#setext-regular-expressions">Regular expressions</a></p>
</li>
<li>
<p><a href="#setext-terminal-descriptions">Terminal descriptions</a></p>
</li>
<li>
<p><a href="#setext-imports">Imports</a></p>
</li>
<li>
<p><a href="#setext-scanner-hooks">Scanner hooks</a></p>
</li>
<li>
<p><a href="#setext-specifying-grammars">Specifying grammars using SeText</a></p>
</li>
<li>
<p><a href="#setext-parser-hooks">Parser hooks</a></p>
</li>
<li>
<p><a href="#setext-usage-hints">Usage hints</a></p>
</li>
<li>
<p><a href="#setext-generated-scanners-parsers">Generated scanners/parsers</a></p>
</li>
</ul>
</div>
<div class="sect2">
<h3 id="setext-lexical-syntax">SeText lexical syntax</h3>
<div class="paragraph">
<p>SeText supports the following comments:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Everything after <code>//</code> until the end of the line is a comment.</p>
</li>
<li>
<p>Everything from <code>/*</code> up to the next <code>*/</code>, possibly spanning multiple lines, is a comment.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>SeText keywords may be used by escaping them with a <code>$</code> character.</p>
</div>
<div class="paragraph">
<p>Whitespace (spaces, tabs, and new lines) are essentially ignored.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-specifying-lexical-syntax">Specifying lexical syntax using SeText</h3>
<div class="paragraph">
<p>Terminals can be specified as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@terminals:
@keywords Operators = and or;
@keywords Functions = log sin cos tan;
end
@terminals:
IDTK = "$?[a-zA-Z_][a-zA-Z0-9_]*" {scanID};
end</code></pre>
</div>
</div>
<div class="paragraph">
<p>Here we specified two groups of terminals.
The first group specifies two keyword (sub-)groups, named <code>Operators</code> and <code>Functions</code>.
For these keywords (<code>and</code>, <code>or</code>, <code>log</code>, etc), terminals are created (<code>ANDKW</code>, <code>ORKW</code>, <code>LOGKW</code>, etc).
Furthermore, the keyword group names (<code>Operators</code> and <code>Functions</code>) may be used as non-terminals in the grammar, to recognize exactly one of the keyword terminals created for that keyword group.</p>
</div>
<div class="paragraph">
<p>The second group specifies an <code>IDTK</code> terminal, defined by a regular expression (see below).
The <code>{scanID}</code> part indicates that the resulting tokens should be passed to the <code>scanID</code> method in the hooks class (see below), to allow post-processing.
Post-processing methods are also allowed for keyword identifiers, such as <code>sin</code> and <code>cos</code> in the example.</p>
</div>
<div class="paragraph">
<p>SeText generated scanners use longest match when recognizing tokens.
If two or more terminals recognize the same longest match, priorities are used to resolve the conflict.
For the example above, the first group of terminals has priority over the second group, thus giving the keywords priority over the identifiers.
That is, <code>@terminals</code> groups listed earlier in the specification have higher priority than <code>@terminals</code> groups listed later in the specification.
If two terminals accept the same input, and they are defined within the same group (they have the same priority), then the specification is invalid.</p>
</div>
<div class="paragraph">
<p>It is also possible to use scanner states:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@terminals:
"//.*";
"/\*" -&gt; BLOCK_COMMENT;
@eof;
end
@terminals BLOCK_COMMENT:
"\*/" -&gt;;
".";
"\n";
end</code></pre>
</div>
</div>
<div class="paragraph">
<p>The first group of terminals is for the default state, as no state name is specified.
Single line comments (<code>// ...</code>) are detected using the first regular expression.
This expression is not given a name, and can thus not be used in parser rules.</p>
</div>
<div class="paragraph">
<p>The second regular expression detects the start of block comments (<code>/*</code>) and switches the scanner to the <code>BLOCK_COMMENT</code> state.</p>
</div>
<div class="paragraph">
<p>The second group of terminals is detected only when the scanner is in the <code>BLOCK_COMMENT</code> state, as indicated by the <code>BLOCK_COMMENT</code> state name after the <code>@terminals</code> keyword.
Everything except for the end of the comment is ignored (no name for the terminals, and no new scanner state).
The end of block comments (<code>*/</code>) makes the scanner go back to the default scanner state (arrow without state name).</p>
</div>
<div class="paragraph">
<p>The <code>@eof</code> terminal indicates that end-of-file is allowed in a scanner state (in this case, the default scanner state).</p>
</div>
<div class="paragraph">
<p>For every scanner, the name of the Java class to generate should be specified, as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@scanner some.package.SomeScanner;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The scanner class must not be a generic class.
Imports (see below) can be used to shorten the specification of the Java class name.</p>
</div>
<div class="paragraph">
<p>Shortcuts can be used for reuse of regular expressions:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@shortcut identifier = "$?[a-zA-Z_][a-zA-Z0-9_]*";
@terminals:
ID2TK = "{identifier}.{identifier}";
ID3TK = "{identifier}.{identifier}.{identifier}";
end</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is possible to use shortcuts in other shortcuts, as long as a shortcut is defined before its use.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-regular-expressions">Regular expressions</h3>
<div class="paragraph">
<p>Regular expressions are enclosed in double quotes.
Within them, the following are supported:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>a</code> for character <code>a</code>, for any <code>a</code> (special characters need escaping).</p>
</li>
<li>
<p><code>\n</code> for the new line character (Unicode U+0A).</p>
</li>
<li>
<p><code>\r</code> for the carriage return character (Unicode U+0D).</p>
</li>
<li>
<p><code>\t</code> for the tab character (Unicode U+09).</p>
</li>
<li>
<p><code>\a</code> for character <code>a</code>, for any <code>a</code> (especially useful for escaping special characters).</p>
</li>
<li>
<p><code>\\</code> for character <code>\</code> (escaped).</p>
</li>
<li>
<p><code>\"</code> for character <code>"</code> (escaped).</p>
</li>
<li>
<p><code>(x)</code> for regular expression <code>x</code> (allows for grouping).</p>
</li>
<li>
<p><code>xy</code> for regular expression <code>x</code> followed by regular expression <code>y</code>.</p>
</li>
<li>
<p><code>x*</code> for zero or more times regular expression <code>x</code>.</p>
</li>
<li>
<p><code>x+</code> for one or more times regular expression <code>x</code>.</p>
</li>
<li>
<p><code>x?</code> for zero or one times regular expression <code>x</code>.</p>
</li>
<li>
<p><code>.</code> for any ASCII character except <code>\n</code> (new line, Unicode U+0A).</p>
</li>
<li>
<p><code>x|y</code> for either regular expression <code>x</code> or regular expression <code>y</code> (but not both).</p>
</li>
<li>
<p><code>[abc]</code> for exactly one of the characters <code>a</code>, <code>b</code> or <code>c</code>.</p>
</li>
<li>
<p><code>[a-z]</code> for exactly one of the characters <code>a</code>, <code>b</code>, &#8230;&#8203;, or <code>z</code>.
This notation is called a character class.
Note that the ranges of characters are based on their ASCII character codes.</p>
</li>
<li>
<p><code>[^a]</code> for any ASCII character except for character <code>a</code>.
This notation is called a negated character class.</p>
</li>
<li>
<p><code>{s}</code> for the regular expression defined by shortcut <code>s</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>To include special characters, they must always be escaped, wherever they occur in the regular expression.
For instance, regular expression <code>[a\^]</code> recognizes either character <code>a</code> or character <code>^</code> (but not both).
Here the <code>^</code> character is escaped, as it is a special character (it may be used at the beginning of a character class to invert the character class).</p>
</div>
<div class="paragraph">
<p>New lines are not allowed in the regular expressions themselves.
Obviously, it is possible to detect new lines using regular expressions.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-terminal-descriptions">Terminal descriptions</h3>
<div class="paragraph">
<p>Terminals can be given an end user readable description (just before the semicolon), for use in parser error messages:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@terminals:
@keywords Operators = and // "and"
or; // "or"
IDTK = "[a-z]+" [an identifier]; // an identifier
ID2TK = "[A-Z]+" [ an identifier ]; // an identifier
ASNGTK = ":="; // ":="
@eof; // end-of-file
X = "[abc]"; // X
"[def]"; // no description</code></pre>
</div>
</div>
<div class="paragraph">
<p>Keyword literals (<code>ANDTK</code> and <code>ORTK</code> in the example above) have the keywords surrounded by double quotes as default description.
Similarly, terminals defined by regular expressions without choice (no character classes, star operators, etc) and using only 'graphical' characters (no control characters, end-of-file, new lines, etc) also have the literal text that they match (surrounded by double quotes) as default description (see <code>ASGNTK</code> in the example above).
The end-of-file token has <code>end-of-file</code> as default description.
Keywords that don&#8217;t have a description and don&#8217;t have default descriptions as described above, get the name of the terminal as description (see <code>X</code> in the example above).
If they don&#8217;t have a name, they have no description.</p>
</div>
<div class="paragraph">
<p>Nameless terminals are not used by the parser, and therefore do not require a description.
The end-of-file terminal has a default description, and can not be given a custom description.
Giving a terminal a custom description if it already has a default description, leads to a warning.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-imports">Imports</h3>
<div class="paragraph">
<p>Java classes/types can be specified in SeText specifications using their fully quantified names, optionally with generic type parameters:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">java.util.String
java.util.List
java.util.List&lt;java.util.String&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>but it is also possible to use imports:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@import java.util.String;
@import java.util.String as string;
@import java.util;
@import java.util as u;</code></pre>
</div>
</div>
<div class="paragraph">
<p>The first import imports <code>java.util.String</code> as <code>String</code>.
The second imports the same type as <code>string</code>.
The third import imports the <code>java.util</code> package as <code>util</code>.
The fourth import imports that same package as <code>u</code>.
After these imports, the following all refer to the <code>java.util.String</code> Java type/class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">java.util.String
util.String
u.String
String
string</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is also possible to import generic types, with their type parameters instantiated:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@import java.util.List&lt;java.util.String&gt; as stringList</code></pre>
</div>
</div>
<div class="paragraph">
<p>allowing <code>stringList</code> to be used as a short form for <code>java.util.List&lt;java.util.String&gt;</code>.</p>
</div>
<div class="paragraph">
<p>Note that it is not possible to use imports to shorten other imports.</p>
</div>
<div class="paragraph">
<p>Finally, note that Java types where the first part of the identifier (the part before any dot) does not refer to an import, are considered absolute.
This means that any Java type name not containing a dot, and not referring to an import, is also considered absolute, and thus refers to a class with that name, in the default package.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-scanner-hooks">Scanner hooks</h3>
<div class="paragraph">
<p>As indicated above, the following SeText specification:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@terminals:
IDTK = "$?[a-zA-Z_][a-zA-Z0-9_]*" {scanID};
end</code></pre>
</div>
</div>
<div class="paragraph">
<p>defines a terminal <code>IDTK</code>, which if recognized, is passed to a <code>scanID</code> method for post-processing.
If such a call back hook method is specified, a (non-generic) hooks class is required.
It can be specified as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@hooks some.package.SomeHooks;</code></pre>
</div>
</div>
<div class="paragraph">
<p>As for all Java types, imports can be used.
For this example, the <code>some.package.SomeHooks</code> class must have a default (parameterless) constructor, and an instance method with the following signature:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public void scanID(Token token);</code></pre>
</div>
</div>
<div class="paragraph">
<p>where the <code>Token</code> class is the <code>org.eclipse.escet.setext.runtime.Token</code> class.
The method may perform in-place modifications to the <code>text</code> field of the <code>token</code> parameter.</p>
</div>
<div class="paragraph">
<p>It is allowed to throw <code>org.eclipse.escet.setext.runtime.exceptions.SyntaxException</code> exceptions in the hooks methods.</p>
</div>
<div class="paragraph">
<p>Note that each generated scanner has an inner interface named <code>Hooks</code> that defines all the required call back hook methods.
The hooks class must implement the interface.
This does not apply to scanners that don&#8217;t have any terminals with call back hooks.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-specifying-grammars">Specifying grammars using SeText</h3>
<div class="paragraph">
<p>All SeText grammars start with one or more start symbols:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@main Program : some.package.ProgramParser;
@start Expression : some.package.ExpressionParser;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This specifies two start symbols, the non-terminals <code>Program</code> and <code>Expression</code>.
Each start symbol further specifies the parser class that should be generated for that start symbol.
Once again, imports are allowed, and the classes must be non-generic.</p>
</div>
<div class="paragraph">
<p>There are two types of start symbols:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>regular start symbols (<code>@start</code> keyword)</p>
</li>
<li>
<p>main start symbols (<code>@main</code> keyword)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The main start symbols are exactly the same as the regular ones, except that they must cover the entire grammar.
That is, all non-terminals must be reachable from each of the main start symbols.
There is no such restriction for regular start symbols.</p>
</div>
<div class="paragraph">
<p>The non-terminals and rules (or productions) can be specified using a BNF like syntax, as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">{java.util.List&lt;some.package.SomeClass&gt;}
NonTerm : /* empty */
| NonTerm2
| NonTerm NonTerm2
| NonTerm3 @PLUSTK NonTerm3 SEMICOLTK
;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This example specifies a non-terminal named <code>NonTerm</code>.
Once reduced, the call back hooks for this non-terminal must result in a Java object of type <code>java.util.List&lt;some.package.SomeClass&gt;</code>.
Here, both generic types and imports are allowed.</p>
</div>
<div class="paragraph">
<p>The non-terminal is defined by four rules (or productions).
The first rule is empty, as clarified by the comment.
The comment is obviously not required.
The second rule consists of a single non-terminal <code>NonTerm2</code>, etc.</p>
</div>
<div class="paragraph">
<p>Each non-terminal rule gives rise to a call back hook method.
The parameters of that method are determined by the symbols that make up that rule.
That is, all non-terminal are always passed to the call back hook method.
Terminals are only passed to the method if they are prefixed with a <code>@</code> character.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-parser-hooks">Parser hooks</h3>
<div class="paragraph">
<p>For parsers, a hooks class must always be specified.
The scanner and all parsers share a single (non-generic) hooks class.
The following specification (from which we omit the scanner part):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-setext" data-lang="setext">@hooks some.package.SomeHooks;
@import some.package.ast;
@main Expression : some.package.ExpressionParser;
{ast.Expression}
Expression : /* empty */
| Expression @PLUSTK Literal
| Expression MINUSTK Literal
;
{ast.Literal}
Literal : @IDTK
| PITK
;</code></pre>
</div>
</div>
<div class="paragraph">
<p>requires a <code>some.package.SomeHooks</code> Java class, with a default (parameterless) constructor, and five methods, with the following signatures:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public Expression parseExpression1();
public Expression parseExpression2(Expression e1, Token t2, Literal l3);
public Expression parseExpression3(Expression e1, Literal l3);
public Literal parseLiteral1(Token t1);
public Literal parseLiteral2();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The return types are determined by the non-terminals.
The names of the methods are formed from the text <code>parse</code>, the name of the non-terminal, and number of the rule, within the non-terminal.
Note that all numbers have equal length.
For instance <code>01</code>, <code>02</code>, <code>03</code>, &#8230;&#8203;, <code>12</code>.
The parameters consist of all the non-terminals that make up the , as well and those terminals with a <code>@</code> before them.
The types of the non-terminal parameters are the types of the corresponding non-terminals.
For terminals, the type is the <code>org.eclipse.escet.setext.runtime.Token</code> class.
The parameter names are formed from their types (first character of the simple name of the class, in lower case), followed by the number of the symbol in the rule, without any <code>0</code> prefixes.
All numbers start counting at one (<code>1</code>).</p>
</div>
<div class="paragraph">
<p>Note that each generated parser has an inner interface named <code>Hooks</code> that defines all the required call back hook methods.
The hooks class must implement the interface(s).
This interface specifies one additional method, which all parser hooks classes must implement:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">public void setParser&lt;Parser&lt;?&gt; parser);</code></pre>
</div>
</div>
<div class="paragraph">
<p>where the <code>Parser&lt;?&gt;</code> class is the <code>org.eclipse.escet.setext.runtime.Parser</code> class.
This method is provided to allow hooks classes access to the parser that creates the hooks class, and its source information.
For more information, see the <code>getSource</code> method of the <code>Parser</code> class.</p>
</div>
<div class="paragraph">
<p>An implementation of a hooks class for this example could look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">package some.package;
import org.eclipse.escet.setext.runtime.Parser;
import org.eclipse.escet.setext.runtime.Token;
import some.package.ast.Expression;
import some.package.ast.Literal;
public class SomeHooks implements ExpressionParser.Hooks {
@Override
public void setParser(Parser&lt;?&gt; parser) {
// No need to store this...
}
@Override
public Expression parseExpression1() {
return null; // Do something more useful here...
}
@Override
public Expression parseExpression2(Expression e1, Token t2, Literal l3) {
return null; // Do something more useful here...
}
@Override
public Expression parseExpression3(Expression e1, Literal l3) {
return null; // Do something more useful here...
}
@Override
public Literal parseLiteral1(Token t1) {
return null; // Do something more useful here...
}
@Override
public Literal parseLiteral2() {
return null; // Do something more useful here...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is allowed to throw <code>org.eclipse.escet.setext.runtime.exceptions.SyntaxException</code> exceptions in the hooks methods.
Furthermore, it is allowed to add fold regions to the parser (which then needs to be stored as it is provided via the <code>setParser</code> hook method), using the <code>addFoldRange</code> methods of the <code>org.eclipse.escet.setext.runtime.Parser</code> class.</p>
</div>
</div>
<div class="sect2">
<h3 id="setext-usage-hints">Usage hints</h3>
<div class="paragraph">
<p>Here are some hints on using SeText:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>It is recommended to name the generated and hooks classes, using the following convention: <code>XyzScanner</code>, <code>XyzParser</code>, <code>XyzHooks</code>, for the scanner, parser, and hooks classes of a language <code>Xyz</code> or <code>XYZ</code>.
For parsers for a part of a language, it is recommended to name the generated parsers <code>XyzPartParser</code>, for non-terminal <code>Part</code> of language <code>Xyz</code> or <code>XYZ</code>.
Following these naming conventions ensures consistency in the naming of the classes.</p>
</li>
<li>
<p>It is recommended to import the packages that contain the classes used as the types of the non-terminals.
For instance, import the expressions package <code>some.long.package.name.expressions</code> as <code>expressions</code> or <code>exprs</code>, and then use <code>{exprs.SomeClass}</code> as the type for a non-terminal, instead of <code>{some.long.package.name.expressions.SomeClass}</code>.
Importing the package instead of the individual classes reduces the number of imports, and also avoids conflicts between non-terminals names and class names.
For standard Java types, however, it is recommended to import the full type.
For instance, import <code>java.lang.String</code> or <code>java.util.List</code>.</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="setext-generated-scanners-parsers">Generated scanners/parsers</h3>
<div class="paragraph">
<p>The generated scanners and parsers depend on the <code>org.eclipse.escet.setext.runtime</code> and <code>org.eclipse.escet.common.java</code> plug-ins.
Generated scanners and parsers inherit from the <code>org.eclipse.escet.setext.runtime.Scanner</code> class and <code>org.eclipse.escet.setext.runtime.Parser</code> class respectively.
Look at those classes for the public API of generated scanners/parsers, as it should be fairly self-explanatory.</p>
</div>
<div class="paragraph">
<p>Besides the scanner and parser(s), debug output is generated from which the scanner and parser(s) can be analyzed.
In particular, the debug output for the parsers makes it possible to find out the details about conflicts in the grammar.
Furthermore, a skeleton is generated for the hooks class.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setext-using-in-an-eclipse-plugin-project">Using SeText in an Eclipse Plug-in Project</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For a new language, follow these steps:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Create a <em>Plug-in Project</em> in Eclipse.</p>
</li>
<li>
<p>Add the <code>org.eclipse.escet.common.java</code> and <code>org.eclipse.escet.setext.runtime</code> plug-ins to the <em>Required plug-ins</em> in the project&#8217;s manifest.
Also add any plug-ins that define the classes that you will be referring to in the SeText specification.</p>
</li>
<li>
<p>Create the Java package where your scanner, parser(s) and hooks classes are to be stored.</p>
</li>
<li>
<p>Create a text file ending with <code>.setext</code> in that same package.
Fill the specification, and save it.</p>
</li>
<li>
<p>Right click the file in the <em>Project Explorer</em> or <em>Package Explorer</em>, and choose the <em>Generate Parser(s)</em> action.
Alternatively, right click the text editor for the SeText specification and choose the same action.</p>
</li>
<li>
<p>Observe how the files are generated.
Make sure the console is free of warnings and errors.</p>
</li>
<li>
<p>Copy the hooks class skeleton (extension <code>.skeleton</code> to extension <code>.java</code>), and implement the hooks.</p>
</li>
<li>
<p>You are ready to use the scanner and parser(s).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>After changes to the SeText specification:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Regenerate the code, as before.</p>
</li>
<li>
<p>If a <code>Hooks</code> interface has changed, update the hooks class.</p>
</li>
<li>
<p>You are ready to use the modified scanner and parser(s).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It may be a good idea to put the <code>.skeleton</code> file in a version control system.
That way, after regeneration, you can ask for a diff.
You then know what has changed, and how you need to update the hooks class.</p>
</div>
<div class="paragraph">
<p>Also note that if a generated <code>Hooks</code> interface changes after a regeneration, Java will report errors for methods not yet present in the hook class.
Similarly, Java will complain about changed method signatures, and methods that no longer exist in the <code>Hooks</code> interface (and thus have invalid <code>@Override</code> annotations in the hooks class).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setext-limitations-issues">Limitations and issues</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following limitations currently apply:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>SeText only allows for the specification of scanners that accept ASCII input.</p>
</li>
<li>
<p>SeText currently assumes UTF-8 encoded files.
If the input file is actually encoded using a different encoding, scanner exceptions may indicate the wrong character.</p>
</li>
<li>
<p>SeText does not support grammars with conflicts (shift/reduce, reduce/reduce, accept/reduce).</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setext-release-notes">SeText release notes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The release notes for the releases of SeText and the associated tools, as part of the Eclipse ESCET project, are listed below in reverse chronological order.</p>
</div>
<div class="paragraph">
<p>The release notes may refer to issues, the details for which can be found at the Eclipse ESCET <a href="https://gitlab.eclipse.org/eclipse/escet/escet/-/issues">GitLab issues page</a>.</p>
</div>
<div class="paragraph">
<p>See also the Eclipse ESCET <a href="https://www.eclipse.org/escet/escet/#release-notes-chapter-index">toolkit release notes</a> covering those aspects that are common to the various Eclipse ESCET tools.</p>
</div>
<div class="sect2">
<h3 id="version-0-2">Version 0.2</h3>
<div class="paragraph">
<p>Improvements and fixes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Documentation has been adapted to be more like the documentation of the other Eclipse ESCET tools (issue #51).</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="version-0-1">Version 0.1</h3>
<div class="paragraph">
<p>The first release of SeText as part of the Eclipse ESCET project.
This release is based on the initial contribution by the Eindhoven University of Technology (TU/e).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setext-legal">Legal</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The material in this documentation is Copyright (c) 2010, 2021 Contributors to the Eclipse Foundation.</p>
</div>
<div class="paragraph">
<p>Eclipse ESCET and ESCET are trademarks of the Eclipse Foundation.
Eclipse, and the Eclipse Logo are registered trademarks of the Eclipse Foundation.
Other names may be trademarks of their respective owners.</p>
</div>
<div class="paragraph">
<p><strong>License</strong></p>
</div>
<div class="paragraph">
<p>The Eclipse Foundation makes available all content in this document ("Content").
Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the MIT License.
A copy of the MIT License is available at <a href="https://opensource.org/licenses/MIT" class="bare">https://opensource.org/licenses/MIT</a>.
For purposes of the MIT License, "Software" will mean the Content.</p>
</div>
<div class="paragraph">
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may apply to your use of any object code in the Content.
Check the Redistributor&#8217;s license that was provided with the Content.
If no such license exists, contact the Redistributor.
Unless otherwise indicated below, the terms and conditions of the MIT License still apply to any source code in the Content and such source code may be obtained at <a href="http://www.eclipse.org" class="bare">http://www.eclipse.org</a>.</p>
</div>
</div>
</div>
</div>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
messageStyle: "none",
tex2jax: {
inlineMath: [["\\(", "\\)"]],
displayMath: [["\\[", "\\]"]],
ignoreClass: "nostem|nolatexmath"
},
asciimath2jax: {
delimiters: [["\\$", "\\$"]],
ignoreClass: "nostem|noasciimath"
},
TeX: { equationNumbers: { autoNumber: "none" } }
})
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data, node) {
if ((node = data.script.parentNode) && (node = node.parentNode) && node.classList.contains("stemblock")) {
data.math.root.display = "block"
}
return data
})
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.9/MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>
<!--
Copyright (c) 2010, 2021 Contributors to the Eclipse Foundation
See the NOTICE file(s) distributed with this work for additional
information regarding copyright ownership.
This program and the accompanying materials are made available under the terms
of the MIT License which is available at https://opensource.org/licenses/MIT
SPDX-License-Identifier: MIT
-->
<div id="footer">
<div id="footer-text">
<a href="https://www.eclipse.org">Eclipse Home</a>
|
<a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a>
|
<a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a>
|
<a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a>
|
<a href="https://www.eclipse.org/legal">Eclipse Legal</a>
</div>
</div>
</body>
</html>