Парсер уравнений (выражений) с приоритетом?

Трудный путь

Вы хотите 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

2022-10-28T12:06:38+00:00