Comments 14
Всё-таки на Rust, с его-то паттерн матчингом, инлайн функциями и макросами, некоторые моменты куда проще написать по сравнению с Java. Вот этот огромный fn tokenize() с макросами был бы намного короче. Конечно, главное, не переусердствовать. Спасибо за статью, жду продолжения.
того самого OwnLang от Animmon’а
Про первое слышал, а вот второго никак не припомню, ахах.
Всё-таки на Rust, с его-то паттерн матчингом, инлайн функциями и макросами, некоторые моменты куда проще написать по сравнению с Java. Вот этот огромный fn tokenize() с макросами был бы намного короче. Конечно, главное, не переусердствовать. Спасибо за статью, жду продолжения.
того самого OwnLang от Animmon’а
Про первое слышал, а вот второго никак не припомню, ахах.
блин, неловко это говорить, когда сам пишешь кучу опечаток, но в тексте много орфографических ошибок, которые немного сбивают с чтения. будет неплохо, если автор придумает что-нибудь против этого.
Синтаксис языка будет Python-подобным
А потом идет пример на Rust-подобном языке (;
Вообще, лексер гораздо проще написать через Logos. Да и эффективнее это.
Также, лучше чтобы tokenize была функцией str -> Tokens, а не методом Lexer-а...
Я написал, что пишем язык с нуля, тобиш без использования библиотек. Так еще статья обучающая созданию простого языка, и я хочу, чтобы целевой читатель понимал как работают все вещи под капотом.
По поводу лексера:
Во-первых, в этой функции надо будет создавать обьект лексера, чтобы был общий контекст. Иначе нужно будет передавать довольно много аргументов условно в tokenize_number: позицию, исхожник, список токенов.
Во-вторых, без обьекта Lexer падает гибкость. С обьектом можно будет добавить опции для лексера и т.д.
По поводу использования библиотек - ок.
Во-первых, в этой функции надо будет создавать обьект лексера, чтобы был общий контекст.
Ну так создайте, в чём проблема. Можете даже сделать реализацию функции tokenize как Lexer::new(s).tokenize(). Суть ведь не в этом.
Суть в том, чтобы публичный интерфейс был простым для простых использований. Если понадобятся опции — сделаете функцию tokenize_with_opts; ну либо уже через объект лексера. См каноничный пример serde_json::from_str.
Тогда, если есть контекст, смысл делать функцию? В любом случае обрабатывать удобнее внутри контекста, а не использовать его снаруже. К тому же, можно сделать функцию tokenize отдельной, которая бы создавала лексер и сразу вызывала функцию lexer.tokenize, и таким образом будет удобный для модификаций лексер и простой удобный юзерский интерфейс.
См каноничный пример serde_json::from_str.
Я посмотрел реализацию этого, и там всеровно есть контекст Deserialize, в котором все обрабатывается, а from_str - просто обертка
pub fn from_str<'a, T>(s: &'a str) -> Result<T>
where
T: de::Deserialize<'a>,
{
from_trait(read::StrRead::new(s))
}К тому же, можно сделать функцию tokenize отдельной, которая бы создавала лексер и сразу вызывала функцию lexer.tokenize, и таким образом будет удобный для модификаций лексер и простой удобный юзерский интерфейс.
Об этом и речь. Не имею ничего против контекста. Просто не нужно показывать его в публичном интерфейсе.
Создание своего языка программирования на Rust #1: Лексер