Что делать, если экранируемый (ые) символ (ы) экранирован? - PullRequest
2 голосов
/ 23 февраля 2011

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

Пример: на простом языке, где строки разделяются двойным-quotes (") и любые кавычки в данной строке экранируются обратной косой чертой (\): для ввода "We \said, \"We want Moshiach Now\"" - что следует делать с буквой s в saidкоторый сбежал?

Ответы [ 4 ]

4 голосов
/ 23 февраля 2011

Я предпочитаю, чтобы лексер скулил, когда это происходит. Лексер / парсер должен быть строг с синтаксисом; всегда можно ослабить это позже. Если вы небрежны, вы обнаружите, что не можете отменить решение, которое, как вы думали, вы не приняли.

Предположим, что вы изначально решили трактовать " обратную косую черту not-an-escape " как эту пару символов, а "T" это не спасение сегодня. Некоторое время спустя вы решаете расширить язык и хотите, чтобы "\ T" означало что-то особенное, и вы меняете свой язык.

Вы найдете разгневанную толпу программистов, штурмующих ваш дизайнерский замок, потому что для них «\ T» означает «\» «T» (или «T» в зависимости от вашего решения по умолчанию), и ты просто сломал их код. Вы опускаете голову от стыда, отказываетесь от решения, а потом понимаете ... упс, больше нет доступных escape-символов!

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

Если ваш язык не будет успешным, вам может быть все равно.

1 голос
/ 23 февраля 2011

Большинство систем интерпретируют косую черту, как говорит Уилл Хартунг, за исключением для буквенно-цифровых символов, которые по-разному используются в качестве псевдонимов для управляющих кодов, классов символов, границ слов, начала шестнадцатеричных последовательностей, маркеров области регистра, шестнадцатеричных иливосьмеричные цифры и т. д. \s в частности часто означает пробел в регулярных выражениях в стиле perl5.JavaScript, который интерпретирует его как 's' в одном контексте и как пробел в другом, страдает от незначительных ошибок из-за этого выбора.Рассмотрим /foo\sbar/ против new RegExp('foo\sbar').

1 голос
/ 23 февраля 2011

Очевидно, что в большинстве систем символ экранирования означает «взять следующий символ дословно», поэтому экранирование «не экранируемого» символа обычно безвредно.Впоследствии проблема возникает, когда вы добираетесь до сравнений и т. Д., Где буквальный текст не представляет фактическое значение (именно здесь вы видите множество проблем с безопасностью, особенно с такими вещами, как URL-адреса).

Так что с одной стороныстороны, вы можете принять только ограниченное количество экранированных символов.В этом смысле у вас есть «escape-последовательность», а не экранированный символ (\ x - это полная последовательность, а не \, за которым следует x).Это похоже на самый безопасный механизм, и писать его не очень обременительно.

Другой вариант - убедиться, что вы «канонизируете» все, что сравниваете, с помощью некоторого набора правил.Как правило, это означает, что необходимо удалить все escape-последовательности заранее, перед сравнением и сравнением только конечных значений, а не литералов.

1 голос
/ 23 февраля 2011

Что ж, одним из способов решения этой проблемы является то, что обратный слеш означает просто обратный слеш, когда он предшествует неисключаемому символу.Вот что делает Python:

>>> print "a\tb"
a   b
>>> print "a\tb\Rc"
a   b\Rc
...