у меня есть что-то вроде этогоPyparsing с дополнительным на левой
IDENTIFIER = Word(alphas + '_', alphanums + '_') #words
GENERIC_TYPE = Regex('[a-zA-Z_]+[a-zA-Z0-9_]*(\<[a-zA-Z0-9_]+\>)?') #List<string> or int
AMF = Keyword('public') | Keyword('private') | Keyword('protected') #method modifier
SFMF = Optional(Keyword('static')) & Optional(Keyword('final')) #static and final modifiers
Для этого примера:
res = (Optional(AMF) +
SFMF +
IDENTIFIER).parseString('Method')
print(res)
он печатает: ['Method']
, но если добавить Optional(GENERIC_TYPE)
:
res = (Optional(AMF) +
SFMF +
Optional(GENERIC_TYPE) +
IDENTIFIER).parseString(text)
print(res)
он печатает ['int', 'Method']
для text='int Method'
BUT вызывает исключение для 'final Method'
(или просто 'Method'
):
pyparsing.ParseException: Expected W:(abcd...,abcd...) (at char 12), (line:1, col:13)
Похоже Pyparsing не видит факультативную вещи, потому что если GENERIC_TYPE не является обязательным (как много вещей перед ним) он должен пойти дальше и разобрать IDENTIFIER часть.
UPDATE:
Проблема, кажется, в логике анализа. Если есть два одинаковых шаблона, а один из них - Необязательный, тогда анализатор не проверяет, является ли он вторым. Например:
m = Optional('M') + Literal('M')
m.parseString('M')
синтаксический анализатор совпадает с «M» в первой части, а затем пропускает неопциональные Буквальное часть.
Итак, теперь я могу разобрать его так, чтобы он соответствовал второму. Это может быть не конец строки или строки, поэтому я не могу использовать это.
Спасибо большое! Больше, чем я хотел. Я знал, что решение есть где-то. Это круто!) Я хотел бы добавить, что я переопределил GENERIC_TYPE на 'g = Forward()' 'g << Word (alphas + '_', alphanums + '_') + Дополнительно (Подавить ('<') + Group (g) + Необязательный (Подавить (',') + Group (g)) + Подавить ('>')) 'возможно, это будет полезно для кого-то. – fantomasdnb