Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -3,7 +3,7 @@ chrMap=: '()';'"';' ',LF,TAB,CR
NB. state columns correspond to the above character classes
NB. first digit chooses next state.
NB. second digit is action 0: do nothing, 1: start word, 2: end word
NB. second digit is action 0: do nothing, 1: start token, 2: end token
states=: 10 10#: ".;._2]0 :0
11 21 00 31 NB. state 0: initial state
12 22 02 32 NB. state 1: after () or after closing "

View file

@ -0,0 +1,38 @@
String.prototype.parseSexpr = function() {
var t = this.match(/\s*("[^"]*"|\(|\)|"|[^\s()"]+)/g)
for (var o, c=0, i=t.length-1; i>=0; i--) {
var n, ti = t[i].trim()
if (ti == '"') return
else if (ti == '(') t[i]='[', c+=1
else if (ti == ')') t[i]=']', c-=1
else if ((n=+ti) == ti) t[i]=n
else t[i] = '\'' + ti.replace('\'', '\\\'') + '\''
if (i>0 && ti!=']' && t[i-1].trim()!='(' ) t.splice(i,0, ',')
if (!c) if (!o) o=true; else return
}
return c ? undefined : eval(t.join(''))
}
Array.prototype.toString = function() {
var s=''; for (var i=0, e=this.length; i<e; i++) s+=(s?' ':'')+this[i]
return '('+s+')'
}
Array.prototype.toPretty = function(s) {
if (!s) s = ''
var r = s + '(<br>'
var s2 = s + Array(6).join('&nbsp;')
for (var i=0, e=this.length; i<e; i+=1) {
var ai = this[i]
r += ai.constructor != Array ? s2+ai+'<br>' : ai.toPretty(s2)
}
return r + s + ')<br>'
}
var str = '((data "quoted data" 123 4.5)\n (data (!@# (4.5) "(more" "data)")))'
document.write('text:<br>', str.replace(/\n/g,'<br>').replace(/ /g,'&nbsp;'), '<br><br>')
var sexpr = str.parseSexpr()
if (sexpr === undefined)
document.write('Invalid s-expr!', '<br>')
else
document.write('s-expr:<br>', sexpr, '<br><br>', sexpr.constructor != Array ? '' : 'pretty print:<br>' + sexpr.toPretty())

View file

@ -1,75 +1,65 @@
/*REXX program parses an S-expression and displays the results. */
/*REXX program parses an S-expression and displays the results. */
input= '((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))'
say 'input:' /*indicate what is being shown. */
say input /*echo the input to the screen. */
say copies('',length(input)) /*display a header fence. */
$.= /*stem array to hold the tokens. */
groupO.1 = '{' ; groupC.1 = '}' /*grouping symbols (Open & Close)*/
groupO.2 = '[' ; groupC.2 = ']' /* " " " " " */
groupO.3 = '(' ; groupC.3 = ')' /* " " " " " */
groupSym = 3 /*the number of grouping symbols.*/
# = 0 /*the number of tokens. */
tabs = 10 /*used for indenting the levels. */
q.1 = "'" /*literal string delimiter, 1st. */
q.2 = '"' /* " " " 2nd. */
numLits = 2 /*number of kinds of literals. */
seps = ',;' /*characters used for separation.*/
atoms = ' 'seps /*characters used to sep atoms. */
level = 0 /*current level being processed. */
quoted = 0 /*quotation level (when nested). */
groupu = /*used to go ↑ an expresion level*/
groupd = /* " " " ↓ " " " */
do n=1 for groupSym /*handle for # grouping symbols. */
atoms = atoms || groupO.n || groupC.n
groupu = groupu || groupO.n
groupd = groupd || groupC.n
end /*n*/
say 'input:'; say input /*display the input data string to term*/
say copies('',length(input)) /*also, display a header fence. */
groupO.= /*default value for grouping symbols. */
groupO.1 = '{' ; groupC.1 = '}' /*grouping symbols (Open & Close). */
groupO.2 = '[' ; groupC.2 = ']' /* " " " " " */
groupO.3 = '(' ; groupC.3 = ')' /* " " " " " */
# = 0 /*the number of tokens found (so far). */
tabs = 10 /*used for the indenting of the levels.*/
q.1 = "'" /*literal string delimiter, first. */
q.2 = '"' /* " " " second. */
numLits = 2 /*the number of kinds of literals. */
seps = ',;' /*characters used for separation. */
atoms = ' 'seps /*characters used to separate atoms. */
level = 0 /*the current level being processed. */
quoted = 0 /*quotation level (when nested). */
groupu = /*used to go ↑ an expression level. */
groupd = /* " " " ↓ " " " */
$.= /*the stem array to hold the tokens. */
do n=1 while groupO.n\=='' /*handle the number of grouping symbols*/
atoms =atoms || groupO.n || groupC.n
groupu=groupu || groupO.n
groupd=groupd || groupC.n
end /*n*/
literals=
do k=1 for numLits
literals = literals || q.k
end /*k*/
do k=1 for numLits
literals=literals || q.k
end /*k*/
!=
/*═════════════════════════════════════start of the text parsing.═══════*/
do j=1 to length(input); _ = substr(input,j,1)
if quoted then do
!=! || _
if _==literalStart then quoted=0
iterate
end
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ text parsing ▒▒▒▒▒▒▒▒*/
do j=1 to length(input); _=substr(input,j,1) /**/
/**/
if quoted then do; !=! || _ /**/
if _==literalStart then quoted=0 /**/
iterate /**/
end /**/
/**/
if pos(_,literals)\==0 then do; literalStart=_ /**/
!=! || _ /**/
quoted=1 /**/
iterate /**/
end /**/
/**/
if pos(_,atoms)==0 then do; !=! || _ ; iterate; end /**/
else do; call add!; !=_; end /**/
/**/
if pos(_,literals)==0 then do /**/
if pos(_,groupu)\==0 then level=level+1 /**/
call add! /**/
if pos(_,groupd)\==0 then level=level-1 /**/
if level<0 then say 'oops, mismatched' _ /**/
end /**/
end /*j*/ /**/
/**/
call add! /*handle any residual tokens.*/ /**/
if level\==0 then say 'oops, mismatched grouping symbol' /**/
if quoted then say 'oops, no end of quoted literal' literalStart /**/
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
if pos(_,literals)\==0 then do
literalStart = _
! = ! || _
quoted = 1
iterate
end
if pos(_,atoms)==0 then do; !=! || _ ; iterate; end
else do; call add!; ! = _ ; end
if pos(_,literals)==0 then do
if pos(_,groupu)\==0 then level=level+1
call add!
if pos(_,groupd)\==0 then level=level-1
if level<0 then say 'oops, mismatched' _
iterate
end
end /*j*/
call add! /*handle any residual tokens. */
if level\==0 then say 'oops, mismatched grouping symbol'
if quoted then say 'oops, no end of quoted literal' literalStart
/*═════════════════════════════════════end of text parsing.═════════════*/
do j=1 for #
say $.j
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────ADD! subroutine─────────────────────*/
add!: if !\='' then do
#=#+1
$.#=left('',max(0,tabs*(level-1)))!
end
!=
return
do j=1 for #; say $.j; end /*display the tokens to the terminal. */
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
add!: if !\='' then do; #=#+1; $.#=left('', max(0, tabs*(level-1)))!; end; !=
return