Динамический (?) Парсер

Существует ли синтаксический анализатор, который генерирует дерево AST / синтаксического анализа во время выполнения? Что-то вроде библиотеки, которая будет принимать строку грамматики EBNF или что-то подобное и выдавать структуру данных?

  • Я знаю о antlr, jlex и им подобных. Они генерируют исходный код, который может это сделать. (хотелось бы пропустить этап компиляции)
  • Я знаю Boost :: Spirit, который использует некоторую черную магию с синтаксисом C++ для генерации таких вещей во время выполнения (определенно намного ближе к тому, что я хочу, но я слабак, когда дело доходит до C++. И это все еще несколько ограничение, потому что ваша грамматика жестко запрограммирована)
  • Я ничего не знаю о python или ruby, хотя компилятор компилятора вполне может быть эффективен на таком языке ...

Теперь я знаю о комбинаторах парсеров. (спасибо, Джонас) И некоторые библиотеки (спасибо eliben)

кстати, я также недавно заметил Анализ грамматик выражений, что звучит круто, если кто-то его реализует (они говорят, что Perl 6 будет иметь его, но Perl ускользает от моего понимания)

Я думаю, что вас интересуют парсеры, а не только лексические анализаторы. Как правило, лексический анализатор создает поток токенов из потока входных символов. Парсер создает AST из потока токенов. Вы можете подумать об изменении формулировки своего вопроса, чтобы привлечь нужную аудиторию.

Greg Mattes 09.10.2008 05:57

аюп. не знаю, о чем я говорю. парсеры. в этом смысле имеет больше смысла.

Ellery Newcomer 09.10.2008 06:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
2
3 871
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Lambda the Ultimate обсудила парсер, который позволяет расширения синтаксиса.

I'm projecting writing a compiler that would allow syntax extensions (some kind of compile-time metaprogramming). I don't want to have a very powerful system, so I've thought about just having:

{syntax: while (condition) do code}
while (condition, code) => // actual execution

and replace every pattern that matches the syntax with a call to the function. However, I don't know where to start to get the lexer and parser running, because usual tools such as Flex/Bison or ANTLR (I would like to write the compiler in C#) don't seem to allow this.

Could you provide me any direction on where to go next? I've also read that Scheme or Haskell could be better languages to achieve this task. And of course, I'm open to any suggestion about the actual idea to implement them.

Да, конечно !

Во всех динамических языках этого очень просто достичь, потому что код можно легко сгенерировать и оценить во время выполнения. Я порекомендую две альтернативы:

  • В Perl используйте Parse :: RecDescent. Он берет свою грамматику из строки, и вы определенно можете попросить его сгенерировать новый синтаксический анализатор из новой строки во время выполнения.
  • В Python рассмотрите PLY. Вы можете легко сгенерировать функции со строками документации во время выполнения и запустить на ней PLY.

Я лично рекомендую вариант Python, хотя он может быть не актуален, если вы знаете Perl, но не Python.

Для полноты картины я должен отметить, что вы можете сделать это и с Lex & Yacc, но это сложно. Вам нужно будет сгенерировать файл Lex / Yacc из вашей грамматики во время выполнения, скомпилировать в C, скомпилировать его в общую библиотеку и загрузить во время выполнения. Это звучит как научная фантастика, но некоторые инструменты на самом деле делают это для сложных требований эффективности и динамичности.

Удачи.

JFlex, расширение JLex для Java, позволяет выполнять компиляцию во время выполнения, но это довольно непростая задача.

Ответ принят как подходящий

Взгляните на комбинаторы синтаксического анализатора, который, я думаю, может вам помочь. Используя эту технику, можно создавать синтаксические анализаторы во время выполнения. Одним из популярных комбинаторов синтаксического анализатора является Парсек, который использует Haskell в качестве основного языка. Из документация по parsec:

Combinator parsers are written and used within the same programming language as the rest of the program. There is no gap between the grammar formalism (Yacc) and the actual programming language used (C)

Parsers are first-class values within the language. They can be put into lists, passed as parameters and returned as values. It is easy extend the available set of parsers with custom made parsers specific for a certain problem

Если вы используете .NET, обратите внимание на файл библиотека комбинаторов парсеров для F#.

Что ты собираешься разбирать? В C или C++ у вас не будет парсера во время выполнения, поэтому он недоступен без дополнительной библиотеки. Однако для многих языков программирования это верно.

Все парсеры по умолчанию являются «динамическими», когда вы их реализуете. Даже в C.

Если язык, который вы собираетесь анализировать, является вашим собственным: написание парсеров - вещь, которую нужно выучить самостоятельно. Даже с генераторами парсеров это работа сама по себе. Однако после того, как вы его изучите, это станет довольно простым. Однако специальные приемы, такие как синтаксис с отступом, по-прежнему будут сложными, и вам потребуются хорошие и обширные тесты, чтобы убедиться, что синтаксический анализатор делает то, что вы хотите. Я написал парсер, поэтому знаю.

Отступы Python соответствуют HTML? Неплохая идея.

Ellery Newcomer 18.10.2008 07:43

Если вам больше подходит Java, есть порт библиотеки Haskell Parsec - JParsec. Очень мощный, хотя документация невелика.

Вы можете заставить его выполнить прямой лексический анализ, а затем выполнить фазу синтаксического анализа, но вы можете делать некоторые интересные вещи с помощью динамического лексирования и динамических грамматик.

Головоломки крутят.

Поскольку все это на Java (ваш Parser - это POJO), вы можете проводить рефакторинг, выполнять TDD и все, что вы привыкли делать на Java. Это главное преимущество более традиционного подхода ANTLR / JavaCC / JJTree.

[Dropincc.java] http://pfmiles.github.com/blog/dropincc-dot-java-the-ultimate-tool-to-create-dsls-in-java/ "Dropincc.java - динамический генератор парсеров на чистом java".

Это позволяет вам определять правила грамматики на языке программирования java и не требует изучения дополнительных обозначений. Никаких других инструментов командной строки использовать не нужно. Вы можете определить, скомпилировать и «оценить» ваш новый язык на чистом java.

Перейдите по ссылке, чтобы получить дополнительную информацию.

[Домашняя страница проекта] https://github.com/pfmiles/dropincc.java

Другие вопросы по теме