Парсер уравнений (выражений) с приоритетом?
Трудный путь
Вы хотите recursive descent parser.
Чтобы получить algorithms приоритет, вам нужно мыслить parser рекурсивно, например, используя parser вашу тестовую строку,
1+11*5
чтобы equations сделать это вручную, вам parser нужно будет прочитать 1
, затем algorithms увидеть плюс и начать совершенно algorithm-design новый «сеанс» рекурсивного algorithms анализа, начиная с 11
... и parser обязательно разобрать 11 * 5
на equation свой собственный фактор, что parsers дает дерево разбора с 1 + (11 * 5)
.
Все parsing это кажется таким болезненным equation даже для попытки объяснить, особенно algorithm с учетом дополнительной беспомощности parsers C. Видите ли, после разбора equation 11, если бы вместо * на самом equations деле был +, вам пришлось algorithm-design бы отказаться от попытки parse создания термина и вместо parse этого анализировать сам 11
как algorithm-design фактор. Моя голова уже взрывается. Это algorithms возможно с рекурсивной приличной parse стратегией, но есть способ parser получше...
Легкий (правильный) способ
Если вы используете equations инструмент GPL, такой как parse Bison, вам, вероятно, не algorithms нужно беспокоиться о проблемах algorithm с лицензированием, поскольку parsing код C, созданный bison, не equations подпадает под действие GPL parse (IANAL, но я почти уверен, что algorithm-design инструменты GPL не навязывают parse GPL). на сгенерированном algorithms коде/двоичных файлах; например, Apple equations компилирует код, например, Aperture parser с GCC, и они продают его algorithm-design без GPL указанного кода).
Download Bison (или parser что-то подобное, ANTLR и algorithms т. д.).
Обычно есть пример algorithms кода, на котором вы можете algorithm просто запустить bison и parsing получить желаемый код C, демонстрирующий algorithm этот четырехфункциональный parsing калькулятор:
http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html
Посмотрите на equations сгенерированный код и убедитесь, что parser это не так просто, как кажется. Кроме parse того, преимущества использования equations такого инструмента, как Bison, заключаются algorithm в следующем: 1) вы чему-то equation учитесь (особенно если вы parser читаете книгу Dragon и изучаете algorithm-design грамматику), 2) вы избегаете parse NIH попыток заново изобретать parser колесо. С настоящим инструментом algorithms генератора синтаксических algorithm анализаторов у вас действительно equations есть надежда на масштабирование parsers позже, показывая другим людям, которых algorithm вы знаете, что синтаксические equations анализаторы являются областью equations инструментов синтаксического algorithm-design анализа.
Обновление:
Люди здесь дали много parser дельных советов. Мое единственное algorithms предупреждение против того, чтобы algorithm пропускать инструменты синтаксического algorithm-design анализа или просто использовать parser алгоритм Shunting Yard или equation ручной рекурсивный синтаксический parsers анализатор, заключается в parsers том, что маленькие игрушечные equations языки1 могут когда-нибудь parsing превратиться в большие настоящие algorithm-design языки с функциями (sin, cos algorithms , log) и переменные, условия parsing и циклы for.
Flex/Bison вполне parse может быть излишним для небольшого algorithm простого интерпретатора, но parsers одноразовый парсер+оценщик algorithm-design может вызвать проблемы в algorithm дальнейшем, когда необходимо algorithms внести изменения или добавить parser функции. Ваша ситуация будет equation варьироваться, и вам нужно parser будет использовать свое суждение; просто algorithm-design не punish other people for your sins [2] и не создавать менее parser чем адекватный инструмент.
Мой любимый инструмент для парсинга
Лучший equation в мире инструмент для работы equation — это библиотека Parsec (для рекурсивных algorithm парсеров), которая поставляется parsing с языком программирования algorithm-design Haskell. Она очень похожа parsers на BNF или на какой-то специализированный algorithm инструмент или предметно-ориентированный parsing язык для синтаксического equation анализа (пример кода [3]), но algorithms на самом деле это обычная algorithm библиотека на Haskell, то parse есть она компилируется на algorithm том же этапе сборки, что parse и остальную часть вашего equation кода на Haskell, и вы можете algorithms написать произвольный код parsers на Haskell и вызывать его parser в своем синтаксическом анализаторе, и parsers вы можете смешивать и сопоставлять algorithms другие библиотеки все в одном коде. (Кстати, встраивание parser подобного языка синтаксического parsers анализа в язык, отличный algorithm-design от Haskell, приводит к большому algorithms количеству синтаксической algorithms хлама. Я сделал это на C#, и algorithm-design это работает довольно хорошо, но algorithm-design не так красиво и лаконично.)
Примечания:
1 Ричард parser Столмен говорит, в Why you should not use Tcl
Главный algorithm урок Emacs заключается в equations том, что язык для расширений parsers не должен быть просто «языком parsers расширения». Это должен algorithms быть настоящим языком программирования, предназначен equations для написания и поддержания содержательные equations программы. Потому что люди захочет algorithms это сделать!
[2] Да, я навсегда parsing боюсь использовать этот «язык».
Также parsing обратите внимание, что, когда parsers я отправил эту запись, предварительный parser просмотр был правильным, но equations Недостаточно адекватный синтаксический анализатор SO съел мой закрывающий тег привязки в первом абзаце, доказывая, что с парсерами equation не стоит шутить, потому что, если parser вы используете регулярные algorithms выражения и один от хаков algorithm вы, вероятно, поймете что-то тонкое и маленькое неправильно.
[3] Фрагмент синтаксического parsing анализатора Haskell с использованием algorithm Parsec: калькулятор с четырьмя equation функциями, дополненный показателями parsers степени, круглыми скобками, пробелами parsers для умножения и константами equations (такими как pi и e).
aexpr = expr `chainl1` toOp
expr = optChainl1 term addop (toScalar 0)
term = factor `chainl1` mulop
factor = sexpr `chainr1` powop
sexpr = parens aexpr
<|> scalar
<|> ident
powop = sym "^" >>= return . (B Pow)
<|> sym "^-" >>= return . (\x y -> B Pow x (B Sub (toScalar 0) y))
toOp = sym "->" >>= return . (B To)
mulop = sym "*" >>= return . (B Mul)
<|> sym "/" >>= return . (B Div)
<|> sym "%" >>= return . (B Mod)
<|> return . (B Mul)
addop = sym "+" >>= return . (B Add)
<|> sym "-" >>= return . (B Sub)
scalar = number >>= return . toScalar
ident = literal >>= return . Lit
parens p = do
lparen
result <- p
rparen
return result
algorithm
parsing
equation
Парсер уравнений (выражений) с приоритетом?
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.