Проблема в том, что Тацу по умолчанию пропускает пробелы, включая переводы строк, между элементами. Поэтому, когда вы применяете правило '#define' constantename [constante]
для ввода:
#define _TEST_
#define _TEST02_ "test02"
Сначала сопоставляется #define
с '#define'
, затем пропускается пробел, затем сопоставляется _TEST_
с constantename
, , затем пропускается символ новой строки , а затем сопоставляется #define _TEST02_ "test02"
с ANY
(через constante
).
Обратите внимание, что именно такого поведения вы бы хотели (я полагаю), если бы не было новой строки:
#define _TEST_ #define _TEST02_ "test02"
Здесь вы хотите вывод ["#define", "_TEST_", "#define _TEST02_ \"test02\""]
, верно? По крайней мере, препроцессор C будет обрабатывать его так же, как в этом случае.
Итак, это говорит нам о том, что перевод строки является значительным. Поэтому вы не можете игнорировать это. Вы можете сказать Tatsu игнорировать только символы табуляции и пробелы (не переводы строк), передавая whitespace = '\t '
в качестве опции при создании парсера или добавив эту строку в грамматику:
@@whitespace :: /[\t ]+/
Теперь вам нужно будет явно указывать новые строки везде, где должны идти новые строки, поэтому ваше правило становится:
define ='#define' constantename [constante] '\n';
Теперь ясно, что константа, если она присутствует, должна появиться до разрыва строки, поэтому для строки #define _TEST_
будет понятно, что константы нет.
Обратите внимание, что вы также хотите, чтобы правило соответствовало пустым строкам, поэтому пустые строки не являются синтаксическими ошибками.