Лексеры / токенизаторы и наборы символов - PullRequest
4 голосов
/ 11 февраля 2010

При конструировании лексера / токенизатора ошибочно полагаться на функции (в C ), такие как isdigit / isalpha / ...? Насколько я знаю, они зависят от локали. Должен ли я выбрать набор символов, сконцентрироваться на нем и сам составить карту символов, из которой я смотрю классификации? Тогда проблема становится в возможности лексировать несколько наборов символов. Создаю ли я один лексер / токенизатор для каждого набора символов или пытаюсь закодировать тот, который написал, так что единственное, что мне нужно сделать, - это изменить отображение символов. Каковы общие практики?

Ответы [ 4 ]

3 голосов
/ 11 февраля 2010

Сейчас я бы сконцентрировался на том, чтобы заставить лексер работать сначала с использованием простого набора символов ASCII, затем, когда лексер работает, добавить поддержку отображения для различных типов символов, таких как UTF-16 и поддержку локали.

И нет, нельзя полагаться на функции ctype, такие как isdigit, isalpha и т. Д. *

На самом деле, может быть, на более позднем этапе есть Posix-эквивалент ctype для широких символов ' wctype.h ', поэтому в ваших интересах определить макрос, позже ... так что вы сможете прозрачно изменить код для обработки различных наборов локалей ...

#ifdef LEX_WIDECHARS
#include <wctype.h>
#define isdigit  iswdigit
#else
#define isdigit
#endif

Было бы определено что-то подобное в этом контексте ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

2 голосов
/ 11 февраля 2010

Вероятно, вы не слишком далеко продвинетесь в попытке создать локальный чувствительный синтаксический анализатор - он сведет вас с ума. ASCII отлично работает для большинства задач анализа - не боритесь с этим: D

Если вы хотите бороться с этим и использовать некоторые классификации символов, вам следует обратиться к библиотеке ICU , которая религиозно реализует Unicode.

2 голосов
/ 11 февраля 2010

Функции ctype.h не очень удобны для символов, которые содержат что-то кроме ASCII. Языковой стандарт по умолчанию - C (по сути, такой же, как ASCII на большинстве компьютеров), независимо от того, какой системный языковой стандарт. Даже если вы используете setlocale для изменения языкового стандарта, есть вероятность, что система использует набор символов с длиной более 8 битных символов (например, UTF-8), и в этом случае вы не сможете отличить ничего полезного от одного символа.

Широкие символы правильно обрабатывают больше дел, но даже они выходят из строя слишком часто.

Итак, если вы хотите надежно поддерживать не-ASCII-пространство, вы должны сделать это самостоятельно (или, возможно, использовать существующую библиотеку).

Примечание: ASCII имеет только коды символов 0-127 (или 32-127), и то, что некоторые называют 8-битным ASCII, на самом деле является другим набором символов (обычно CP437, CP1252, ISO-8859-1 и часто также что-то еще).

1 голос
/ 11 февраля 2010

Как правило, вы должны спросить себя:

  • что именно вы хотите сделать, какой разбор?
  • Какие языки вы хотите поддерживать, широкий или только западноевропейский?
  • В какой кодировке вы хотите использовать UTF-8 или локализованную 8-битную кодировку?
  • Какую ОС вы используете?

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

Тем не менее:

  • если вы работаете с UTF-8, вы не можете, потому что только ASCII будет покрыт, вы не можете, потому что все за пределами ASCII занимает более одного байта.
  • Если вы хотите поддерживать восточные языки, все ваши предположения о синтаксическом анализе были бы неверными, например, китайцы не используют пробел для разделения слов. Большинство языков даже не имеют верхнего или нижнего регистра, даже алфавит, основанный на иврите или арабском языке.

Итак, что именно вы хотите сделать?

Я бы посоветовал взглянуть на библиотеку ICU с различными итераторами разбиения или другие наборы инструментов, такие как Qt, которые предоставляют базовый анализ границ.

...