Создание многопоточного скрипта lex / yaac - PullRequest
1 голос
/ 02 апреля 2019

У меня есть код lex / yaac, который собирает некоторые данные после анализа файла.Этот файл в определенном формате.Рассмотрим этот формат:

Формат файла:

ABC
  Something something
ABC
  Something something
....
....

Код Lex / Yacc сейчас является последовательным.Можно ли сделать код многопоточным для одного файла, разделив его на куски, разделенные ABC.

С чего начать?

Я буду рад поделиться более подробной информацией, если это необходимо.

1 Ответ

0 голосов
/ 04 апреля 2019

Проблема в том, что вы не знаете, где находятся разделители, пока не проведете лексический анализ файла. Если разделители не являются однозначно контекстуальными (что не будет иметь место, если ваш синтаксис включает в себя такие вещи, как комментарии или строки в кавычках), вы не сможете начать анализ в произвольной точке файла, не зная контекста этой точки. Поэтому в обычных случаях для нахождения разделителей требуется линейное сканирование.

Вы можете передавать часть файла в отдельный поток синтаксического анализатора каждый раз, когда вы идентифицируете конечные точки блока. Это потребует сканирования фрагмента дважды (один раз для начального сканирования разделителя и второй раз для точного анализа), но он все равно может быть выигрышным, если синтаксический анализ выполняется относительно медленно. Вы могли бы избежать второго сканирования, сохранив поток токенов в памяти и передав потоку синтаксического анализатора список токенов, но вполне может оказаться, что управление памятью и другие операции учета списков токенов являются такими же или более дорогими, чем лексическое сканирование. Это будет зависеть от множества факторов, поэтому эксперименты и бенчмаркинг в вашем конкретном случае использования будут необходимы.

Если разделители полностью однозначны и фрагменты относительно короткие, вы можете разделить файлы на страницы некоторого удобного размера и дать каждому потоку свои собственные страницы для анализа. Когда потоку назначается страница, он должен будет пропустить исходные данные, пока не найдет первый разделитель; когда он достигнет конца страницы, он должен будет продолжить сканирование оставшейся части текущего фрагмента на следующей странице. Так что будет немного повторяющегося сканирования, но если куски будут короткими по отношению к размеру страницы, это будет не так уж плохо. Опять же, сравнение вашего конкретного варианта использования будет полезно. И, опять же, вы можете сделать это только в том случае, если вы можете однозначно распознать разделитель, ничего не зная о лексическом контексте.

...