+
1
|
list
|
skin
|
login
|
editor
α-wwwiki
::
parser
user:none
(3332 bytes)
_h1 the parser _p A standard (LISP) parser is built on 3 steps : tokenize, build a tree and evaluate. Lambdatalk uses another approach based on a unique regular expression matching and evaluating in a unique loop a sequence of s-expressions °°{first rest}°°, from the innermost leaves to the root. This is a quick look into the parser's engine translating °°{first rest}°° forms into HTML expressions. {pre °° // 1) APPLYING SYNTAX TO THE CODE STRING function doSyntax( str ) { // input : lambdatalk code str = preprocessing( str ); str = doLoop( str ); str = postprocessing( str ); return str; // output : HTML/CSS code } // 2) GLOBAL VARIABLES var first = '', // global tag/operator/function in {first rest} rest = '', // global text to be transformed by first html = {}; // global html dictionary // 3) THE MAIN LOOP // is based on a unique regular expression : var loop_rex = /\{([^\s{}]*)(?:[\s]*)([^{}]*)\}/g; // explanation : 1) / start of the regexp 2) \{ begins with a { 3) ([^\s{}]*) everything except a space or { or } : first 4) (?:[\s]*) zero or several spaces 5) ([^{}]*) everything except { or } : rest 6) \} ends with a } 7) / end of the regexp 8) g go next // used in only one line of Javascript to replace // {first rest} forms by HTML expressions ; inspired by // http://blog.stevenlevithan.com/archives/reverse-recursive-pattern function doLoop( str ) { while (str != (str = str.replace( loop_rex, dispatch ))) ; return str; } // 4) DISPATCH FUNCTION var dispatch = function (m, f, r) { first = (f != undefined)? f : ''; rest = (r != undefined)? r.replace(/^s+|s+$/g, '') : ''; if (html.hasOwnProperty( first )) // return html[first](); // here some more code for extended functionalities // see [[JS.js|meca/JS.js]] for more informations return '(' + first + rest + ')'; // default behaviour }; // 5) THE HTML DICTIONARY var htmltags = [ // register HTML tags 'div', 'span', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'table', 'tr', 'td', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'hr', 'b', 'i', 'u', 'sup', 'sub', 'del', 'pre','center', 'blockquote', 'a', 'img', 'iframe', 'embed', 'canvas', 'input', ]; for (var i=0; i < htmltags.length; i++) { html[htmltags[i]] = function( tag ) { return function () { var attributes = ''; var m = rest.match( /@ @[^@]*@ @/ ); if (m != null) { rest = rest.replace( m[0], '' ); attributes = m[0].replace( /@/g, '' ); } return '< '+tag+' '+attributes+'>'+rest+'< /'+tag+'>'; }; }(htmltags[i]); } // AN OPERATOR FOR CATCHING ATTRIBUTES html['@'] = function () { // {@ some attributes} return '@ @'+rest+'@ @'; // -> @ @some attributes@ @ }; °°} _h3 more _ul The full code (extended functions, browser's integration) can be seen here : [[JS.js|meca/JS.js]]. _ul See page [[substitution]] to see how the main loop works on s-expressions. _ul ...