Я думаю, что ваша проблема в том, что ваши регулярные выражения для t_TABLE
и t_COLUMN
также соответствуют вашим зарезервированным словам (SELECT и FROM).Другими словами, SELECT a FROM b;
токенизируется до чего-то вроде COLUMN COLUMN COLUMN COLUMN END
(или некоторой другой неоднозначной токенизации), и это не соответствует ни одному из ваших произведений, поэтому вы получаете синтаксическую ошибку.
В качестве быстрой проверки работоспособности,измените эти регулярные выражения так, чтобы они точно совпадали с тем, что вы печатаете:
t_TABLE = r'b'
t_COLUMN = r'a'
Вы увидите, что синтаксис SELECT a FROM b;
проходит, потому что регулярные выражения 'a' и 'b' не совпадаютВаши зарезервированные слова.
И есть еще одна проблема, заключающаяся в том, что регулярные выражения для TABLE и COLUMN также перекрываются, поэтому лексер не может токенизироваться без неоднозначности в отношении этих токенов.
Есть тонкий, но соответствующий раздел в документации PLY относительно этого.Не уверен, что это лучший способ объяснить это, но дело в том, что сначала проходит этап токенизации, поэтому он не может использовать контекст из ваших производственных правил, чтобы узнать, встречался ли он с токеном TABLE или COLUMN.Вам нужно обобщить их в какой-то токен ID
, а затем отсеять их во время разбора.
Если бы у меня было больше энергии, я бы попытался еще немного проработать ваш код и найти реальное решение.в коде, но я думаю, что, поскольку вы уже выразили, что это учебное упражнение, возможно, вы будете довольны мной, указывая в правильном направлении.