Это соответствует 10(
, потому что 1
соответствует [^+-]
, 0
соответствует 0
и (
соответствует [^0-9]
.
Причина, по которой я использовал приведенное выше выражение:вместо гораздо более простого (0 | [+ -]? [1-9] [0-9] *) происходит из-за неспособности синтаксического анализатора распознавать неправильные выражения, такие как 012.
Как так?Используя приведенное выше регулярное выражение, 012
будет распознаваться как два токена: 0
и 12
.Не приведет ли это к ошибке в вашем парсере?
По общему признанию, это не приведет к очень хорошему сообщению об ошибке, поэтому лучшим подходом было бы просто использовать [0-9]+
в качестве регулярного выражения, а затем использовать действие для проверкиза ведущий ноль.Таким образом, 012
будет единственным токеном, и лексер может выдать ошибку или предупреждение о начальном нуле (я предполагаю, что вы действительно хотите запретить начальные нули - не используйте их для восьмеричных литералов).
Вместо проверки в действии вы также можете оставить свое регулярное выражение, а затем добавить еще одно для целых чисел с начальным нулем (например, 0[0-9]+ { warn("Leading zero"); return INT; }
), но я бы пошел с проверкой в действии, поскольку это простая проверкаи это делает регулярное выражение коротким и простым.
PS: Если вы сделаете -
и +
частью целочисленного токена, что-то вроде 2+3
будет выглядеть как целое число 2
, за которым следуетцелое число +3
, а не целые числа 2
и 3
с токеном +
между ними.Поэтому, как правило, лучше не делать знак частью целочисленного токена и вместо этого разрешать префиксные операторы +
и -
в анализаторе.