Синтаксис / Логическая проверка В Javascript?
Я строю решение для клиента, которое позволяет им создавать очень простой код, теперь я сделал некоторую базовую проверку синтаксиса, но я застрял в проверке переменных.
Я знаю, что JSLint делает это, используя Javascript, и мне было интересно, если кто-нибудь знает хороший способ сделать это.
Так, например, скажем, пользователь написал код
moose = "barry"
base = 0
if(moose == "barry"){base += 100}
Затем я пытаюсь найти способ уточнить, что выражение "если" имеет правильный синтаксис, если переменная moose была инициализирована и т. Д., И т. Д., Но я хочу сделать это без сканирования символьно, код является мини-языком построен только для этого приложения, поэтому он очень простой и не требует управления памятью или чем-то в этом роде.
Я думал о разделении сначала по Carriage Return, а затем по Space, но нечего сказать, что пользователь не напишет что-то вроде 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;}
Это базовый пример того, как будет использоваться язык.
Спасибо за все ваши ответы, я исследовал парсер и создать его было бы гораздо сложнее, чем требовалось, выполнив несколько тестов с тысячами строк кода, и обнаружил, что посимвольный анализ занимает всего несколько секунд, даже если одноядерный P4 с 512 Мб памяти (что намного меньше, чем использует клиент)
Я решил создать основанный на PHP инструмент проверки синтаксиса, который будет проверять информацию и преобразовывать переменные и т. Д. В действительный код PHP во время его проверки (чтобы его можно было вызывать позже без перекомпиляции), используя его вместо javascript. Это кажется более подходящим. и позволит возникать более сложный код, не мешая процессу проверки
Это заняло всего час, и у меня есть код, который может проверить правильность оператора if и не смущен вложенными выражениями if, пробелами или нечетными выражениями. Осталось проверить очень мало, тогда как синтаксический анализатор и полноценный язык сценариев заняло бы намного больше времени
Вы все дали мне много думать, и я оценил соответствующие ответы, спасибо
3 ответа
Если вы действительно хотите это сделать - и под этим я подразумеваю, что вы действительно хотите, чтобы ваше программное обеспечение работало правильно и предсказуемо, без каких-то странных особых случаев "не делайте этого" - вам придется написать реальный парсер для вашего языка. Получив это, вы можете преобразовать любую программу на вашем языке в структуру данных. С такой структурой данных вы сможете проводить все виды анализа кода, включая процедуры, которые, по крайней мере, раньше назывались анализом определения использования и определения использования определения.
Если вы придумали "язык программирования", который позволяет выполнять некоторые сценарии в приложении, то, как бы вы это ни думали, кто-то, в конце концов, напишет с ним поразительно большую программу.
Я не знаю ни одного легкодоступного генератора парсера, который генерирует парсеры JavaScript. Синтаксические анализаторы с рекурсивным спуском не слишком сложны для написания, но они могут быть уродливы в обслуживании и затрудняют расширение синтаксиса (особенно если вы не очень опытны в создании оригинальной версии).
Возможно, вы захотите взглянуть на JS/CC, который является генератором синтаксического анализатора, который генерирует синтаксический анализатор для грамматики в Javascript. Вам нужно будет выяснить, как описать ваш язык, используя BNF и EBNF. Кроме того, JS/CC имеет свой собственный синтаксис (который несколько близок к фактическому BNF/EBNF) для указания грамматики. Учитывая грамматику, JS/CC сгенерирует синтаксический анализатор для этой грамматики.
Другой вариант, как сказал Пойнти, - написать свой собственный лексер и парсер рекурсивного спуска с нуля. Если у вас есть BNF/EBNF, это не так сложно. Недавно я написал парсер из EBNF на Javascript (грамматика была довольно простой, так что написать YMMV было не так сложно).
Чтобы ответить на ваши комментарии о том, что это "специфично для клиента". Я также добавлю свой собственный опыт здесь. Если вы предоставляете язык сценариев и среду сценариев, нет лучшего пути, чем настоящий анализатор.
Работа с особыми случаями через группу if-elses будет ужасно болезненной и кошмаром обслуживания. Когда я был новичком в колледже, я пытался писать на своем родном языке. Это было до того, как я узнал что-нибудь о парсерах с рекурсивным спуском или просто о парсерах в целом. Я сам понял, что код можно разбить на токены. Оттуда я написал чрезвычайно громоздкий парсер, использующий кучу if-elses, а также разбивающий токены на пробелы и другие символы (именно то, что вы описали). Конечный результат был ужасен.
Когда я прочитал о синтаксических анализаторах с рекурсивным спуском, я написал грамматику для своего языка и с легкостью создал парсер в 10-й раз, когда мне потребовалось написать свой оригинальный синтаксический анализатор. Серьезно, если вы хотите сэкономить много боли, напишите настоящий парсер. Если вы пойдете по текущему маршруту, вы навсегда исправите проблемы. Вам придется разбираться со случаями, когда люди помещают пространство не в том месте, или, возможно, у них слишком много (или одно слишком мало) мест. Единственная альтернатива - предоставить чрезвычайно жесткую структуру (т. Е. У вас должно быть ровно x пробелов после этого оператора), что сделает вашу среду сценариев крайне непривлекательной. Фактический парсер автоматически исправит все эти проблемы.
Javascript имеет функцию "Eval".
var code = 'alert(1);';
eval(code);
Это покажет предупреждение. Вы можете использовать eval для выполнения базового кода.