1) Измените Literal("if")
на Keyword("if")
(и так далее, вплоть до Literal("void")
), чтобы предотвратить совпадение с начальным "if" переменной с именем "ifactor"
.
2) nums
, alphas
и alphanums
не являются выражениями, это строки, которые можно использовать с классом Word для определения некоторых типичных наборов символов при определении «слов», таких как «число слово, составленное из чисел ", или" идентификатор - это слово, которое начинается с буквы, за которой следует ноль или более букв ". Так что вместо:
number = nums
identifier = alphas + OneOrMore(alphanums)
хочешь
number = Word(nums)
identifier = Word(alphas, alphanums)
3) Вместо Combine
, я думаю, вы хотите Group
. Используйте Combine
, если хотите, чтобы совпадающие токены были смежными без пробелов, и объединят токены и вернут их как одну строку. Combine
часто используется в таких случаях:
realnum = Combine(Word(nums) + "." + Word(nums))
Без Combine
, синтаксический анализ "3.14"
вернет список строк ['3', '.', '14']
, поэтому мы добавим Combine
, чтобы проанализированный результат для realnum был '3.14'
(который затем можно было бы передать в действие разбора для преобразовать в фактическое плавающее значение 3.14
). Применение Combine
отсутствия промежуточных пробелов также удерживает нас от случайного разбора 'The answer is 3. 10 is too much.'
и думает, что "3. 10"
представляет действительное число.
4) Это не должно вызывать вашу ошибку, но ваша входная строка содержит лотов лишних пробелов. Если ваша грамматика работает, вы сможете анализировать "int x;"
так же, как и "int x ;"
.
Надеюсь, некоторые из этих подсказок помогут вам. Вы читали какие-нибудь статьи или учебники по онлайн-анализу? И, пожалуйста, просмотрите онлайн примеры. Вам нужно хорошо понять, как Word
, Literal
, Combine
и т. Д. Выполняют свои отдельные задачи синтаксического анализа.
5) Вы неправильно реализовали рекурсивные определения для термина и выражения. Вместо присвоения им ''
напишите:
term = Forward()
statement = Forward()
Затем, когда вы действительно захотите определить их с помощью их рекурсивных определений, используйте оператор <<
(и обязательно добавьте RHS в ()
).
term << (... term definition ...)
statement << (... statement definition ...)
Вы можете найти пример рекурсивного синтаксического анализатора здесь и презентацию по базовому использованию синтаксического разбора здесь - более подробно см. В разделе «Списки синтаксического анализа» о том, как обрабатывается рекурсия.