#python #python-3.x #parsing
#python #python-3.x #синтаксический анализ
Вопрос:
Мне нужно переписать грамматику в EBNF. Используйте метод рекурсивного спуска сверху вниз для реализации синтаксического анализатора (т.е. tdrd parser.py ) в python3 для грамматики EBNF. Имя файла входных данных задается из командной строки. Предположим, что между двумя терминалами (например, a a a c c b ) в файле данных есть пробел.
Вот грамматика:
<S> -> <A> c c <B> | <B> d d <A>
<A> -> a <A> | a
<B> -> b <B> | b
Вот код:
import sys
def lexan():
global mitr
try:
return next(mitr)
except StopIteration:
return ''
def match(ch):
global lookahead
if ch == lookahead:
lookahead = lexan()
else:
print("Syntax Error")
exit()
def S():
#<S> -> <A> c c <B> | <B> d d <A>
global lookahead
if lookahead == 'a':
A()
#match('c')
C()
elif lookahead == 'b':
B()
#match('c')
C()
else:
print("Syntax Error")
exit()
def A():
# <A> -> a <A> | a
global lookahead
match('a')
if lookahead == 'a':
A()
def B(): # <B> -> b <B> | b
global lookahead
match('b')
if lookahead == 'b':
B()
def C():
global lookahead
match('c')
if lookahead == 'c':
C()
file = open(sys.argv[1], "r")
wlist = file.read().split()
mitr = iter(wlist)
lookahead = lexan()
S()
if lookahead == '':
print("Pass")
else:
print("Syntax Error")
exit()
Всякий раз, когда я его запускаю: python3 tdrd_parser.py data.txt если я удалю b из файла — я получу «Пропуск». В противном случае — синтаксическая ошибка.
Не могли бы вы помочь?
Комментарии:
1. Откуда
C
взялся? В грамматике нет такого нетерминала. Кроме того, ваша интерпретация вS()
двух производствах верхнего уровня, похоже, останавливается в середине правой части.2. Ну, так что я не очень хорошо разбираюсь в грамматике EBNF, но я подумал, что, поскольку у нас есть c c между A и B, мы должны включить C? Кроме того, я не уверен, почему он застревает? Нужно ли включать больше операторов if?
3. Если я не ошибаюсь, S() должен выглядеть следующим образом: def s(): if lookahead == ‘a’: A() match(‘c’) match(‘d’) B() elif lookahead == ‘b’: match(‘d’) match(‘c’) A() else: print («Синтаксическая ошибка») exit() @rici
4. Закрыть. Согласно вашей грамматике,
A(); match('c'); match('c'); B();
иB(); match('d'); match('d'); A();
. Но это не то, что у вас есть, не так ли? Запускаемая продукцияA()
никогдаB()
не вызывается, поэтому неудивительно, что ab
в конце ввода не распознается.5. @rici теперь имеет смысл! Спасибо, чувак! Попытаюсь реализовать его сегодня! 🙂