LINUX.ORG.RU

Rust vs C

 ,


3

7

Я Rust не знаю.
Допустим решил я написать быстрый лексер (разбиватель токенов),как я делаю это в Си:

typedef struct {
    const char* text;
    size_t      text_len;
    size_t      text_pos;

    const char* token;
    size_t      token_len;
} lexer_t;
 
void lexer_next_token(lexer_t* lexer);

И я могу получить все токены без выделения памяти,я просто иду по тексту и ставлю lexer_t.token в начало токена, и в token_t.token_len записываю длинну токена.А в расте как сделать подобную вещь?Тоже без выделения памяти естественно (ну кроме стека,где выделяется код возврата и 2 size_t для функии next_token).Верней можно ли сделать такое в расте?

Какой-то у вас странный лексический парсер. Толку то от такой структуры? Токены должны быть пронумерованы, идентификаторы — выставлена ссылка на таблицу с типами/значениями. А ваш парсер - ровно половина от всей работы и сам по себе не интересен. По сути потом потребуется ещё проход: читать токены с неудобным интерефейсом start/len и вся «быстрость» будет коту под хвост.

vodz ★★ ()
Ответ на: комментарий от vodz

Ну добавь в структуру их мысленно,и текущую линию,позицию,etc.Я упрощенно написал,но это самое быстрое что я смог придумать,и мне интересно как делается ЭТО в расте.

с неудобным интерефейсом

man define,inline

linuhs_user ()
  • указатель на текст + его длина — это как раз строковый слайс.
  • Тебе только нужно дополнительно указывать время жизни твоего лексера.
O02eg ★★★★★ ()
Последнее исправление: O02eg (всего исправлений: 1)
Ответ на: комментарий от linuhs_user

Я упрощенно написал

Это тот самый случай, когда «ненужно». Сжираем постоянно расширяющуюся память при чтении вместо разумного одного буфера и пачки структур со значениями emun-а ключевых слов или указателя на структуру идентификаторов, где имена аллокируются ровно один раз и в виде удобного zero-terminating.

vodz ★★ ()
Ответ на: комментарий от linuhs_user

Ты просто не осилил мою идею

Ясен пень, как можно осилить то, чего нет. Тупо расставить start/len на постоянно расширяющейся памяти и назвать это «лексером»...

vodz ★★ ()
Ответ на: комментарий от linuhs_user

Это не у меня, а у вас.

Детский сад этот уже начинает доставать. Если есть что сказать конкретно, а не в виде «сам дурак» то напрягитесь. Тренировать головную мышцу — это полезно.

vodz ★★ ()

И я могу получить все токены без выделения памяти,я просто иду по тексту и ставлю lexer_t.token в начало токена, и в token_t.token_len записываю длинну токена

Как это без выделения памяти? Где же хранится lexer_t.token? Поверх входного файла записывается? Как оно влезает?

anonymous ()
Ответ на: комментарий от linuhs_user

Ну так это не «без выделения памяти». Для произвольного текста память под указатель и длину выделять придётся. Хоть бы в виде линейного буфера.

anonymous ()
Ответ на: комментарий от linuhs_user

Показывай где память расширяется

Память при разборе всегда пожирается, так как лексический анализатор не в курсе, на какой стадии находится синтаксический. Но одно дело пожирать память на (лисповские) TOKEN_IS_DEFVAR и т п, вы постояно увеличиваете память буфера чтения исходника на ваши *text/start/len. То есть по сути это не лексер, а входной аллокатор с предварительной расстановки позиций у токенов. Всё бы ничего, если б это действительно было кому-то надо.

vodz ★★ ()
Ответ на: комментарий от anonymous

Ну под структуру,и текст выделить память конечно придеться.Хотя можно и fread/fseek/etc читать,но вдруг текст придет не из файла. Я имею виду что не надо выделять память под каждый токен,и все такое

linuhs_user ()
Ответ на: комментарий от vodz

память буфера чтения

Что это?

а входной аллокатор

Аллоцировать не обязательно,можно сохранять позицию и длинну.
-------------------------------
Я вижу процесс таким Текст -> Мой лексер -> Генерируем AST -> Парсим AST
и где тут выделение памяти кроме как под текст,стрктуру лексера,ветвей AST я не вижу (ну еще память может выделятся когда по AST проходимся,но это уже не то)

linuhs_user ()
Ответ на: комментарий от linuhs_user

Аллоцировать не обязательно,можно сохранять позицию и длинну.

А следующий проход будет снова читать из файла по этим позициям?! Охренеть нужный лексер.

vodz ★★ ()
Ответ на: комментарий от anonymous

В/на стеке.

А это типа не память :) Это мало того, что память, так ещё и ограниченная и медленная при первом расширении. Ладно бы сказали, что в регистрах оно бы поместилось :))

vodz ★★ ()
Ответ на: комментарий от linuhs_user

Ну сохрани нужные для прохода секции

Причём тут ваши «ну», если речь ровно о том, а) почему ваш лексер эталонное ненужно и б) как на самом деле делается.

не для многопроходных текстов надо.

Вы так нихрена не поняли. Ваш лексер потому и бесполезен, что требует второй проход обязательно - надо понять что за токены скрываются в ваших *text, вместо того, чтобы как положенно лексеру вписать в структуру сразу TOKEN_XXX.

vodz ★★ ()
Ответ на: комментарий от vodz

надо понять что за токены скрываются в ваших *text

Текст там скрывается.Его получить можно

вписать в структуру сразу TOKEN_XXX

Что это такое?Тип токена?Я и говорю добавь в стрктуру enum token_type;

linuhs_user ()
Ответ на: комментарий от linuhs_user

Что это такое?

Это то, для чего лексер и нужен, работа у него такая, если вы не в курсе.

Я и говорю добавь в стрктуру enum token_type;

Тяжёлый случай. Нахрена добавлять, если надо заменять ваши ненужные text ?

vodz ★★ ()
Ответ на: комментарий от vodz

Тяжёлый случай

Может тогда тебе стоит сейчас уже обратиться к врачу?

если надо заменять ваши ненужные text

Какой смысл заменять?В памяти ничего не занимает,читай вместо текста тип токена,если он есть.Что не так?Тогда показывай мне пример,код какой нибудь который надо лексить/парсить,и где конкретно в моем лексере будет проблема

linuhs_user ()

Вот тоби решение на Расте. Я немного схалявничал с итераторами (skip_while), но замена на нормальную итерацию в общем тривиальна http://goo.gl/h5SSMR

&str - толстый указатель, фактически состоит из указателя на начало и длины.

khrundel ()
Последнее исправление: khrundel (всего исправлений: 2)
Ответ на: комментарий от linuhs_user

Может тогда тебе стоит сейчас уже обратиться к врачу?

Всегда интересовал вопрос, какой диагноз у взрослых людей, прибегающих к такому детсадовскому «аргументу». Слабоумие? Нет нет, это не вам, для вас этот вопрос риторический.

Какой смысл заменять?

Какой смысл оставлять ненужное?

В памяти ничего не занимает

Похоже всё тщетно. Проще забанить вас.

vodz ★★ ()

Подозреваю, что будет типа

struct lexer_t {
    text: &'static str,
    token: &'static str,
} 

impl lexer_t {
    fn lexer_next_token(&self) {
        // ...
    }
}

upd: Пропущены поля специально т.к. скорее всего они нам не понадобятся.

Но лучше, напишите как Вы видите lexer_next_token и я сделаю компилируемый аналог на расте

AntonyRF ()
Последнее исправление: AntonyRF (всего исправлений: 1)

Неправильно ты задачу поставил. В С еще можно на месте декодировать всякие base64, URL encoding, убирать двойные кавычки, добавлять \0 вместо разделителей и пр. А потом по частям раздать в другие функции или хранить как уже готовые данные. Можно и на Rust, конечно, но будет сложнее и для написания и для использования.

anonymous ()