Интересно, что я попробовал ваш лексер на коде моего лексера / оценщика, написанного на JS;) Вы правы, с регулярными выражениями это не всегда хорошо работает.Вот несколько примеров:
rexl.re = {
NAME: /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/,
UNQUOTED_LITERAL: /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/,
QUOTED_LITERAL: /^'(?:[^']|'')*'/,
NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/,
SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/
};
В основном это нормально - только UNQUITED_LITERAL
не распознается, в противном случае все в порядке.Но теперь давайте сделаем небольшое дополнение к нему:
rexl.re = {
NAME: /^(?!\d)(?:\w)+|^"(?:[^"]|"")+"/,
UNQUOTED_LITERAL: /^@(?:(?!\d)(?:\w|\:)+|^"(?:[^"]|"")+")\[[^\]]+\]/,
QUOTED_LITERAL: /^'(?:[^']|'')*'/,
NUMERIC_LITERAL: /^[0-9]+(?:\.[0-9]*(?:[eE][-+][0-9]+)?)?/,
SYMBOL: /^(?:==|=|<>|<=|<|>=|>|!~~|!~|~~|~|!==|!=|!~=|!~|!|&|\||\.|\:|,|\(|\)|\[|\]|\{|\}|\?|\:|;|@|\^|\/\+|\/|\*|\+|-)/
};
str = '"';
Теперь все после того, как регулярное выражение NAME's
испортилось.Это делает 1 большую строку.Я думаю, что последняя проблема в том, что маркер String слишком жадный.Первый может быть слишком умным регулярным выражением для regex
токена.
Редактировать : Мне кажется, я исправил регулярное выражение для токена regex
.В вашем коде замените строки 146-153 (вся часть «следующих символов») следующим выражением:
([^/]|(?<!\\)(?<=\\)/)*
Идея состоит в том, чтобы разрешить все, кроме /
, также разрешить \/
, но неallow \\/
.
Edit : еще один интересный случай, проходит после исправления, но может быть интересно добавить в качестве встроенного тестового примера:
case 'UNQUOTED_LITERAL':
case 'QUOTED_LITERAL': {
this._js = "e.str(\"" + this.value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + "\")";
break;
}
Редактировать : еще один случай.Похоже, он слишком жаден по поводу ключевых слов.См. Кейс:
var clazz = function() {
if (clazz.__) return delete(clazz.__);
this.constructor = clazz;
if(constructor)
constructor.apply(this, arguments);
};
Лекс это как: (keyword, const), (id, ructor)
.То же самое происходит для идентификатора inherits
: in
и herits
.