Синтаксис / Логическая проверка В Javascript? - PullRequest
3 голосов
/ 27 декабря 2010

Я создаю решение для клиента, которое позволяет им создавать очень простой код, теперь я сделал некоторую базовую проверку синтаксиса, но я застрял в проверке переменных.

Я знаю, что JSLint делает этоиспользуя Javascript, и мне было интересно, если кто-нибудь знает хороший способ сделать это.

Так, например, скажем, пользователь написал код

moose = "barry"
base = 0
if(moose == "barry"){base += 100}

Затем я пытаюсь найти способуточнить, что выражение «если» имеет правильный синтаксис, если переменная moose была инициализирована и т. д. и т. д., но я хочу сделать это без сканирования символьно, код является мини-языком, созданным только для этого приложения, поэтому он оченьбазовый и не требует управления памятью или чем-то в этом роде.

Я думал о разделении сначала по Carriage Return, а затем по пробелу, но нечего сказать, что пользователь не напишет что-то вроде moose="barry"или if(moose=="barry") и нечего сказать, что пользователь не будет хранить результат условия в строке.

Очевидно, компиляторы и интерпретаторысделать это в гораздо более широком масштабе, но я не уверен, что они делают это символ за символом, и если они делают, как они оптимизировали?

(Другой вариант, я мог бы отправить его обратно в PHP для обработкичто затем освободит браузер от ответственности)

Любые предложения?

Спасибо

Вариант использования ограничен, синтаксис в этом случае никогда не будет расширяться, языкпростой язык сценариев, позволяющий клиенту создавать уникальную стоимость на основе ввода своих пользователей, конечный результат будет обрабатываться PHP независимо от того, что конечный пользователь не сможет откорректировать расчет, а также для обеспечения некоторой согласованности.

Так, например, скажем, что базовая стоимость составляет £ 1,00, а в форме есть поле «Дополнительные затраты», язык позволит им манипулировать базовой стоимостью относительно поля «Дополнительные расходы».

Итак

base = 1;
if(additional > 100 && additional < 150){base += 50}
elseif(additional == 150){base *= 150}
else{base += additional;}

Это базовый пример использования языка.


Спасибодля всех ваших ответов я исследовал парсер, и его создание было бы гораздо более сложным, чем требовалось, выполнив несколько тестов с тысячами строк кода, и обнаружил, что посимвольный анализ занимает всего несколько секунд даже на одномCore P4 с 512 МБ памяти (что намного меньше, чем использует клиент)

Я решил создать синтаксическую проверку на основе PHP, которая будет проверять информацию и преобразовывать переменные и т. д. в действительный код PHP во время проверки.это (так что он готов к вызову позже без перекомпиляции) с использованием этого вместо javascript, это кажется более подходящим и позволит возникать более сложный код, не мешая процессу проверки

Это заняло всего час, и у меня естьКод, который может проверять правильность оператора if и не смущен вложенными выражениями if, пробелами или нечетными выражениями, проверять очень мало, в то время как анализатор и полноценный язык сценариев заняли бы намного больше времени

Вы все дали мне много о чем подумать, и я оценил соответствующие ответы, спасибо

Ответы [ 3 ]

4 голосов
/ 27 декабря 2010

Если вы действительно хотите сделать это - и под этим я подразумеваю, если вы действительно хотите, чтобы ваше программное обеспечение работало правильно и предсказуемо, без каких-то странных особых случаев "не делайте этого" - вывам придется написать настоящий парсер для вашего языка.Получив это, вы можете преобразовать любую программу на вашем языке в структуру данных.С этой структурой данных вы сможете проводить все виды анализа кода, включая процедуры, которые, по крайней мере, раньше назывались анализом определения использования и определения использования использования.

Если вы придумываете «программирование»язык ", который позволяет выполнять некоторые сценарии в приложении, тогда, независимо от того, насколько вы обыдены, кто-то в конце концов напишет с ним потрясающе большую программу.

Я не знаю ни одного доступного генератора парсерагенерировать парсеры JavaScript.Синтаксические анализаторы с рекурсивным спуском писать не так уж сложно, но они могут быть уродливы в обслуживании и затрудняют расширение синтаксиса (особенно если вы не очень опытны в создании оригинальной версии).

2 голосов
/ 27 декабря 2010

Возможно, вы захотите взглянуть на JS / CC , который является генератором синтаксического анализатора, который генерирует синтаксический анализатор для грамматики в Javascript. Вам нужно будет выяснить, как описать ваш язык, используя BNF и EBNF. Кроме того, JS / CC имеет свой собственный синтаксис (который несколько близок к фактическому BNF / EBNF) для указания грамматики. Учитывая грамматику, JS / CC сгенерирует парсер для этой грамматики.

Другой вариант, как сказал Пойнти, - написать свой собственный лексер и парсер рекурсивного спуска с нуля. Если у вас есть BNF / EBNF, это не так сложно. Недавно я написал парсер из EBNF на Javascript (грамматика была довольно простой, поэтому написать YMMV было не так сложно).

Чтобы ответить на ваши комментарии о том, что это "специфично для клиента". Я также добавлю свой собственный опыт здесь. Если вы предоставляете язык сценариев и среду сценариев, нет лучшего пути, чем настоящий анализатор.

Работа с особыми случаями через группу if-elses будет ужасно болезненной и кошмаром обслуживания. Когда я был новичком в колледже, я пытался писать на своем родном языке. Это было до того, как я узнал что-нибудь о парсерах с рекурсивным спуском или просто о парсерах в целом. Я сам понял, что код можно разбить на токены. Оттуда я написал чрезвычайно громоздкий парсер, использующий кучу if-elses, а также разбивающий токены на пробелы и другие символы (именно то, что вы описали). Конечный результат был ужасен.

Как только я прочитал о синтаксических анализаторах с рекурсивным спуском, я написал грамматику для своего языка и легко создал синтаксический анализатор в 10-й раз, когда мне потребовалось написать свой оригинальный синтаксический анализатор. Серьезно, если вы хотите избавить себя от большого количества боли, напишите фактический парсер. Если вы пойдете по текущему маршруту, вы навсегда исправите проблемы. Вам придется разбираться со случаями, когда люди помещают пространство не в том месте, или, возможно, у них слишком много (или одно слишком мало) мест. Единственная альтернатива - предоставить чрезвычайно жесткую структуру (т. Е. У вас должно быть ровно x пробелов после этого оператора), что может сделать вашу среду сценариев крайне непривлекательной. Фактический парсер автоматически исправит все эти проблемы.

1 голос
/ 27 декабря 2010

Javascript имеет функцию 'eval'.

var code = 'alert(1);';
eval(code);

Это покажет предупреждение. Вы можете использовать 'eval' для выполнения основного кода.

...