Привет, ребята, спасибо за чтение
Сейчас я пытаюсь сделать калькулятор в стиле 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]+
Лексический анализ состоит в проверке того, что нет ничего, что не похоже на одно из терминальных выражений: оператор, префиксы, целое число и число с плавающей запятой. Его можно сократить до одного регулярного выражения:
(я добавил пробелы, чтобы сделать его более читаемым)
var calcPat =
/^ (\s*
( ([+/*%^-]) | ([0-9]+) | ([0-9]+[.,][0-9]+) | (\() | (\)) )
)+ \s* $/;
Если этот тест проходит, запрос является лексически правильным и должен быть проверен грамматикой, чтобы определить, можно ли его вычислить. Это сложная часть.
Я не собираюсь вставлять код, потому что он непонятен и непонятен, но я собираюсь объяснить процесс, которому я следовал, и почему я застрял:
Я создал метод с именем isStatement (string)
, который должен вызывать себя рекурсивно. Основная идея - разбить строку на «потенциальные»
Процесс следующий:
-Если первые два токена представляют собой число, за которым следует оператор:
-Тогда,
- Если остался всего один жетон и это число:
--- Тогда это утверждение.
--- В противном случае проверьте, образуют ли оставшиеся токены оператор (рекурсивный вызов)
-Else, если первый токен является круглой скобкой
-Затем найдите подходящую закрывающую круглую скобку и проверьте, является ли то, что внутри, оператором (рекурсия)
- Также проверьте, есть ли что-то после закрывающей круглой скобки и не образует ли он оператор, связанный со структурой круглых скобок.
Моя проблема в том, что я не могу найти подходящую скобку, когда есть вложенные структуры. Как я могу это сделать? Кроме того, как вы видите, это не совсем общий и чистый алгоритм проверки грамматики. Есть ли у вас идея улучшить этот шаблон?
Большое вам спасибо за то, что вы нашли время, чтобы прочитать все.
] и [
для типов записей F #, объявляющих изменяемые поля, не так ли?