Comments (18)
Стоит также обдумать возможность применения комбинаторов парсеров. Ну не люблю я неприкрытую кодогенерацию, а тот же fparsec весьма хорош.
from lens.
Fparsec мне внешне вполне нравится, но я пока еще не до конца его понял. Нужно выяснить:
- Насколько он пригоден для того, чтобы строить синтаксическое дерево
- Как в нем можно кастомизировать сообщения об ошибках (у нас на кафедре это первое, на что будут смотреть)
from lens.
Я строил дерево вот так: https://github.com/ForNeVeR/Tantalum/blob/master/Voice/Program.fs
(весь трюк - в OperatorPrecedenceParser<T, unit, unit>
)
Однако же, в целом, fparsec нам не очень подойдёт, потому что у нас C#.
from lens.
Мы с тобой вчера приняли решение написать рукопашный парсер (главным образом - из-за проблем отслеживания идентации), но я решил сегодня дать шанс fparsec'у. И вот, он наносит ответный удар: https://github.com/impworks/lens/blob/parser/Lens.Parser/Program.fs
Итак, я вызываю внутри монады parse
код let! i = indentCount
, после чего в нужных местах фигачу do! skipIndent i
. Это позволяет отслеживать блоки кода с отступами относительно начального блока (ведь там можно вместо i
написать i + 1
или что угодно ещё - пока что ради примера я не стал заморачиваться).
Предлагаю, таким образом, наваять парсер-лексер на F#. Отдавать он будет сразу синтаксическое дерево, пригодное для непосредственной компиляции (нужно только написать в functionBody
правильную трансформацию тела функции).
from lens.
Мне субъективно нравится код на фшарпе. Он прямо-таки создан для написания всякого рода парсеров. Но тут возникают два небольших вопроса:
- Нам понадобится еще один проект, в который придется вынести синтаксическое дерево и весь код генерации IL, потому как циклические зависимости проектов если и возможны, то дадут нам сотни геморроя. Или сделать F#-проект основным интерфейсом, а C#'овский - вспомогательным, как библиотеку?
- Для встраиваемого языка хорошо бы иметь одну единственную сборку, но этот вопрос решается с помощью ILMerge.
from lens.
1
1a. Циклические зависимости проектов дотнет не допускает, да и правильно, в общем-то, делает.
1b. У меня как раз есть некие примеры IL-генерации на F#, см. naggum. Правда, я сейчас даже сам не могу там ничего понять. Но это возможно и не особо сложно, факт.
1c. На самом деле, писать совместимый с C# API необязательно на C#.
2
Помимо ILMerge, есть другие способы работать с многосборочными проектами.
2a. Можно делать многомодульные сборки руками (передавая компилятору специальный флаг, чтобы он создавал не DLL, а именно модуль).
2b. Я видел, как чуваки кладут сборку себе в ресурсы, а потом подгружают её в рантайме из ресурсного потока. Но этот метод мне не очень нравится.
from lens.
В целом, наверное, нет особого смысла писать весь код на чистом F# - нам всё равно придётся применять ILMerge, например, чтобы слить проект с кодом fparsec. Хотя, с другой стороны, можно будет просто включить её исходники в проект - и тогда снова появляется соблазн написать всё в одном проекте и на F#.
from lens.
from lens.
Хорошо, постараемся реализовать на F# только необходимый минимум.
В качестве рабочего варианта рассмотрим пока что парсер на F# в отдельной сборке. Синтаксическое дерево - наверное, туда же. А вот обработку дерева и генерацию CIL-кода можно убрать в C#-часть. Таким образом, основная сборка референсит сборку на F#, и всё.
from lens.
Мне кажется странным разлелять описание узлов дерева и генерацию соответствующего им IL-кода. В Mirelle каждая нода имела методы Compile и GetExpressionType. Нужно подумать.
from lens.
А мне видится функциональный подход в виде
static Assembly GenerateAssembly(SyntaxTreeNode root);
from lens.
Так получится god object с неебической тонной методов и огромным свитчом типа if(node is ArrayAssignmentNode) ... else if(...) ...
. Не красиво.
from lens.
В таком случае мы не получаем никакого профита от реализации синтаксического дерева на F# - всё равно в алгебраический тип такое многообразие не засунуть.
from lens.
Тогда я бы сделал три проекта:
- Compiler - C#, все классы синтаксического дерева и методы для генерации IL.
- Parser - F#, парсер и лексер. Зависит от Compiler и Fparsec.
- Frontend - C#. Зависит от Compiler и Parser. Передает строку парсеру, получает дерево, создает сборку, передает ее руту дерева в качестве параметра, запускает сборку на выполнение.
Все равно потом придется мерджить сборки.
from lens.
Годится.
from lens.
https://gist.github.com/3772212
Пример того, как парсить текст по грамматикам, использующим indenting-based blocks. Прислан автором FParsec, значит является источником вселенской мудрости :)
from lens.
Ох нифига себе! Без поллитры не разберёшься...
from lens.
Раз ты приступил к написанию парсера, тикет закрываю.
from lens.
Related Issues (20)
- Операции над функциями
- Мульти-объявление неинициализированных переменных HOT 1
- Ошибка в грамматике
- Интерфейс контекстно-зависимой типизации
- Ошибка при сохранении сборки - файл занят
- Проблема с тестами Translations HOT 1
- Поддержка атрибута Obsolete
- Поддержка Expression<T>
- Fix continuous integration
- Grammar file gets included after package installing HOT 2
- RegisterFunction doesn't seem to work HOT 1
- Ошибка с замыканием в цикле
- Bad IL format HOT 1
- Verbatim strings
- Наведение порядка в коде HOT 1
- LE3063: Only public, static, non-generic methods can be imported! HOT 4
- Улучшение для вывода типов
- Портирование на .NET Core HOT 4
- Properly detect System.Private library
- RegexNamedGroupsTryParseNoThrow test doesn't work
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lens.