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).Верней можно ли сделать такое в расте?



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

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

Можно сделать unsafe указатель,вызывать сишные memcmp,но для этого ли делался раст?)

linuhs_user
() автор топика

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

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

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

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

man define,inline

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

Я делал от скуки себе лисп-интерпретатор,только добавил в стрктуру bool token_is_string; не знаю какие проблемы ты здесь видишь.

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

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

linuhs_user
() автор топика
Ответ на: комментарий от 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
() автор топика
Ответ на: комментарий от anonymous

Для произвольного текста

А типа для предыдущего примера под token и token_len память не выделялась. :)

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

Это уже операционная система решит, где там и сколько выделять, а не ты со своими кольцевыми буферами и прочими ритуальными плясками.

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

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

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

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

В/на стеке.

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

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

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

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

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

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

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

32 битных регистров как раз хватает на стрктуру и функцию)

linuhs_user
() автор топика
Ответ на: комментарий от 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)
Ответ на: комментарий от khrundel

Так понятнее, спасибо.Попробую сейчас свой набросать

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

Можно было и типаж итератора сделать.

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

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

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

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

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

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

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

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

к такому детсадовскому «аргументу»

Говорить про диагнозы и говорить что знаешь какую то истину,это 'по взрослому' ага))

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

Лол

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

Ну, подразумевается, что лексический анализ сложнее сравнения с пробелом. Что-нибудь типа 0x123 скипвайлом не распарсить

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

Ну добавить в него побольше проверок для разбивающих элементов к примеру,я думал что он тормозной просто.

linuhs_user
() автор топика

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

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

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

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

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

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

Обещают, что оптимизатор всё заинлайнит, не должен быть тормозным. Сам не проверял.

khrundel ★★★★
()

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.