Внимaнию новичков предлагаю свой скрипт комплексного разбора листинга, отделяющий вычисления от комментариев, а также разделения операций от операндов.
Каких-тo семь лет тому назад для меня словосочетание "регулярное выражение" звучало магически и мистически. Сначала было достаточно сложно разобраться в них и переварить информацию о них.
Пришлось разработать собственный скрипт и оттачивать практику прямо в режиме "реального времени".
Скрипт
немножечко подогнал сейчас под современные стандарты:
<style>
body {
margin : 0 0 0 0;
}
</style>
<script>
var
srcMost, expMost = /(•*)(?: |((?:"(?:\\.|.)*?"|'(?:\\.|.)*?'|`(?:\\.|.)*?`|[^•"'`])*))(.*)/,
srcCalc, expCalc = /(("|'|`)(\\.|[^\2])*?\2)|([0-9a-z_]+)|(([!#$%&*+-/<=>?|^~])+)|[()]/,
txtArea, resArea,
stopper = 80, // Ограничитель для предотвращения зацикливания
symbol = "•",
i, l, line, stop,
html;
function Init() {
(srcMost = document.getElementsByTagName("input")[0]).value = expMost.source;
(srcCalc = document.getElementsByTagName("input")[1]).value = expCalc.source;
resArea = document.getElementsByTagName("pre")[0];
(txtArea = document.getElementsByTagName("textarea")[0])
.addEventListener("keydown",
function(e) {
if(e.keyCode == 9 && !e.shiftKey ) {
if(document.selection) {
sel = document.selection.createRange();
sel.text = symbol;
} else //MOZILLA and others
if(this.selectionStart || this.selectionStart == '0') {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
this.value = this.value.substring(0, startPos) + symbol + this.value.substring(endPos, this.value.length);
this.selectionStart = startPos + 1;
this.selectionEnd = startPos + 1;
} else {
this.value += symbol;
}
e.preventDefault();
}
});
}
function ParseLine(text) {
var
stop = stopper;
try {
expMost = new RegExp(srcMost.value);
line = expMost.exec(text);
} catch(e) {
return resArea.innerHTML = "Bad regular expression";
}
for(i = 0, l = line.length - 1; -- stop && i <= l; ++ i)
try {
if(line[i])
switch(i) {
case 1: // Основание выражения
html.push(i + ":" + line[i].bold().strike());
break;
case 2: // Основное выражение выделяем
html.push(i + ":" + line[i].bold());
break;
case l: // Зелёный комментарий курсивом
html.push(i + ":" + ("// " + line[i]).italics().fontcolor("green"));
break;
default:// "Лишние" элементы зачёркиваем, делая тусклыми
html.push(i + ":" + line[i].strike().fontcolor("gray"));
break;
}
} catch(e) {
if(line && line.length)
html.push("i/" + line.length + " = " + i + " is " + e);
++ i;
}
resArea.innerHTML = html.join("<br/>") + (stop ? "" : "OVERFLOW!!!");
}
function ParseAll(text) {
var
stop = stopper;
html = new Array();
try {
expMost = new RegExp(srcMost.value);
expCalc = new RegExp(srcCalc.value, "gi");
} catch(e) {
return resArea.innerHTML = "Bad regular expression";
}
text.split(/\r?\n/)
.forEach(function(row) {
row.replace(expMost
,function(str, enter, exprs, comms) {
//line = expMost.exec(row);
//enter = line[1].length;
//exprs = line[2];
//comms = line[3];
html.push("[" + enter + "] " + (exprs ? exprs : "") + (comms ? "//" + comms : ""));
if(exprs && (calc = exprs.match(expCalc)))
for(j = 0; -- stop && j < calc.length; ++ j) {
if(calc[j] != undefined)
html.push(j + ": «" + calc[j] + "»");
}
});
});
resArea.innerHTML = html.join("<br/>") + (stop ? "" : "OVERFLOW!!!");
}
</script></head>
<body onload='Init()'>
<textarea rows=7 cols=80 onkeyup='ParseAll(this.value)'
> Commentary #1
• Commentary #2
•• Foo = `8\'75•'s` + "5\"25•'s " + '3"5•\'s' • Commentary's •
•••Foo = `8\'75•'s` + "5\"25•'s " + '3"5•\'s' • Commentary's •
••dx = (x2 - x1) / (x2 - x1 < 0 ? x1 - x2 : x2 - x1)
a = ((b ! c) # d) $ e % f & g * h + i - j / k < l > m ? n ^ o | p ~ r</textarea><br/>
Most <input type=text style=width:50% value='' onkeyup='html = new Array(); txtArea.value.split(/\r?\n/).forEach(ParseLine)'/><br/>
Calc <input type=text style=width:50% value='' onkeyup='ParseAll(txtArea.value)'/>
<pre></pre>
</body>
P.S.: Для удобства отладки символ табуляции я подменил на "•".
Надеюсь, окажется полезным.
(Его смастерил, когда писал парсер трансляции с ассемблера, так-как
всевозможные многочисленные сервисы не предоставляли возможности отладки разбивки строчек на действия/коментарии и сразу разбивки действия на отдельные операции)