Привет, народ, спасибо, что читаете
В настоящее время я пытаюсь сделать калькулятор в стиле Google. Вы вводите строку, она определяет, можно ли ее вычислить, и возвращает результат.
Я медленно начал с основ: + - / *
и обработки скобок.
Я хочу со временем улучшать калькулятор, и, немного изучив лексический анализ некоторое время назад, я составил список токенов и связанных с ними шаблонов регулярных выражений.
Этот вид работы легко применим к таким языкам, как Lex и Yacc, за исключением того, что я разрабатываю приложение только для Javascript.
Я попытался транскрибировать идею в Javascript, но не могу понять, как правильно и красиво обрабатывать все, особенно вложенные скобки.
Анализ
Давайте определим, что такое запрос калькулятора:
// NON TERMINAL EXPRESSIONS //
query -> statement
query -> ε // means end of query
statement -> statement operator statement
statement -> ( statement )
statement -> prefix statement
statement -> number
number -> integer
number -> float
// TERMINAL EXPRESSIONS //
operator -> [+*/%^-]
prefix -> -
integer -> [0-9]+
float -> [0-9]+[.,][0-9]+
Javascript
Лексический анализ заключается в проверке того, что нет ничего, что не было бы похоже на одно из терминальных выражений: оператор, префиксы, целое число и число с плавающей запятой. Что можно сократить до одного регулярного выражения:
(я добавил пробелы, чтобы было читабельнее)
var calcPat =
/^ (\s*
( ([+/*%^-]) | ([0-9]+) | ([0-9]+[.,][0-9]+) | (\() | (\)) )
)+ \s* $/;
Если этот тест проходит успешно, запрос является лексически правильным и требует проверки грамматики, чтобы определить, можно ли его вычислить. Это сложная часть
Я не буду вставлять код, потому что он не чист и непонятен, но я собираюсь объяснить процесс, которому я следовал, и почему я застрял:
Я создал метод isStatement(string)
, который должен вызывать себя рекурсивно. Основная идея состоит в том, чтобы разбить строку на «потенциальные» операторы и проверить, действительно ли они являются операторами, и сформировать их целиком.
Процесс следующий:
-Если первые два токена представляют собой число, за которым следует оператор:
-Then,
-- Если оставшаяся часть представляет собой всего одну лексему и является числом:
--- Тогда это оператор.
--- В противном случае проверьте, образуют ли оставшиеся лексемы оператор ( рекурсивный вызов)
-Иначе, если первая лексема является круглой скобкой
-Затем, найдите соответствующую закрывающую круглую скобку и проверьте, является ли то, что находится внутри, выражением (рекурсией)
-- Также проверьте, есть ли что-то после закрывающей круглой скобки и образует ли она оператор, связанный со структурой скобок.
В чем проблема ?
Моя проблема в том, что я не могу найти подходящие скобки, когда есть вложенные структуры. Как я могу это сделать? Кроме того, как вы можете видеть, это не особенно общий и чистый алгоритм проверки грамматики. Есть ли у вас какие-либо идеи по улучшению этого шаблона?
Большое спасибо, что нашли время, чтобы прочитать все. Гаэль
(PS: Как вы, наверное, заметили, я не носитель английского языка! Извините за ошибки и все такое!)