2016-10-29 13 views
1

Я изучаю, как работают парсеры, создавая простой рекурсивный анализатор спуска. Однако у меня проблема с определением моей грамматики как LL (1). Я хочу, чтобы иметь возможность проанализировать следующие два утверждения:Проблема, создающая грамматику LL (1)

a = 1 
a + 1 

Чтобы сделать это, я создал следующие правила грамматики:

statement: assignent | expression 
assignment: NAME EQUALS expression 
expression: term [(PLUS|MINUS) term] 
term:  NAME | NUMBER 

Однако это приводит к неоднозначности при использовании LL (1), как если токен NAME встречается в правиле statement, он не знает, является ли он assignment или expression без ожидания.

Python грамматика LL (1), поэтому я знаю, что это возможно, но я не могу понять, как это сделать. Я рассмотрел правила грамматики Python, найденные здесь (https://docs.python.org/3/reference/grammar.html), но я все еще не уверен, как они это реализуют.

Любая помощь будет принята с благодарностью :)

+0

LL (1) не означает, что вы не смотрите вперед, это означает, что у вас есть односторонний взгляд вперед (это то, откуда приходит 1). Когда вы найдете токен NAME, ищите следующий токен, это будет токен EQUALS, PLUS или MINUS, тогда вы знаете, какое правило следует следовать на основе этой информации. – Mephy

+1

Исправьте меня, если я ошибаюсь, но я думал, что единственным взглядом на будущее будет токен NAME? – soarjay

+0

Прошло некоторое время с тех пор, как я изучил компиляторы, и моя терминология может быть неправильной, но я думаю, что NAME - это текущий токен (тот, который дал лексер), а EQUALS/PLUS будет первым маркером с перспективой (тот, который вы «заглянуть», но на самом деле не поп). – Mephy

ответ

2

Просто лечить = как оператор с очень низким приоритетом. Однако (если вам не нужен такой язык, как C, где = действительно является оператором с очень низким приоритетом), вам нужно исключить его из внутренних (например, скотистых) выражений.

Если вы имели только умножение и сложение, вы можете использовать:

expression: factor ['+' factor] 
factor:  term ['*' term] 
term:  ID | NUMBER | '(' expression ')' 

Это руководство для оператора старшинства: имеет более высокий приоритет, так как аргументы + может включать в себя сек но не наоборот. Таким образом, мы могли бы просто добавить задание:

statement: expression ['=' expression] 

К сожалению, это позволило бы, например:

(a + 1) = b 

что нежелательно. Поэтому его нужно устранить, но его можно устранить, когда производство принято (путем проверки формы первого expression), а не самой грамматики. Насколько я понимаю, это то, что делает парсер Python; см. длинный комментарий о test и ключевых словах.

Если вы использовали парсер LR (1) вместо этого, у вас не было бы этой проблемы.