2013-09-01 6 views
0

Я нахожу грамматику для арифметического выражения в префиксной нотации. Однако у меня возникает проблема при анализе отрицательных чисел или вычитаний. Грамматика пример заключается в следующем:Арифметическая грамматика выражения в префиксном обозначении (Java Cup)

precedence right +, -; 
precedence right *, /; 
precedence right uminus; 

E ::= + E E 
    | - E E 
    | * E E 
    |/E E 
    | (E) 
    | - E %prec uminus 
    | id 
    | digit 
    ; 

Но если мой вход - 5 4, это уменьшает 5 в E, рядом уменьшает - E (отрицательный), а затем парсер дает мне ошибку синтаксиса в 4. Правильный должен быть 5 как E, следующий 4 как E, а затем - E E как E. Как я могу решить эту проблему с помощью ассоциативности? или мне нужно переписать мою грамматику?

ответ

1

(Повышен от комментариев)

Ваша грамматика действительно неоднозначна, и декларации старшинства не поможет вам немного.

Рассмотрим Входные данные, состоящий из N- маркеров, а затем M1 маркеров.

- - - - - - - ... - 1 1 1 ... 1 

Для того, чтобы это было выражение, M-1 из - лексем должны быть двоичными, а остальные N-(M-1) унарными, но нет никакого способа узнать, что есть что (если они не являются всеми бинарными).

Даже если угодно сказать, что первые N-(M-1)- s является унарным, вы не можете сказать, что значение N-(M-1) пока вы не читали весь ввод, который означает, что вы не можете разобрать с конечным опережающим просмотром.

Но вся префиксная нотация заключается в том, чтобы избежать необходимости в круглых скобках. Произвольные объявления, подобные приведенным выше, делают невозможным представление альтернативных интерпретаций, поэтому некоторые выражения невозможно представить в префиксной нотации. Это просто неправильно.

Вот простой пример:

- 5 - - - 4 3 1 

либо

5 - (- (4 - (3 - 1))) 
5 - ((- (4 - 3)) - 1) 
5 - (((- 4) - 3) - 1) 

В префиксной нотации, вы должны объявить «арность» каждый оператор, либо неявно (каждый оператор имеет известное число аргументов) или явно используя такую ​​запись, взятую из Пролога:

-/2 5 -/2 -/2 -/1 4 3 1 

В качестве альтернативы, вы можете разграничить аргументы обязательные скобки, как и Лисп/Scheme «S-exprs»:

(- 5 (- (- (- 4) 3) 1)) 
+0

Это относится только к префиксной нотации, я прав? –

+0

@ System.exit Он также относится к нотации «постфикс», также называемой «Поперечная польская нотация» (RPN). Хотя я не совсем уверен, что вы просите. – rici

+0

Я прошу о возможном решении (если оно существует) грамматике для арифметических выражений в префиксе, которая может принимать отрицательные числа/переменные. На самом деле я сделал неоднозначную грамматику для обозначения «в порядке», и она работает, но я столкнулся с этой проблемой (отрицательные числа) с префиксом. –

0

Во-первых, удалите все объявления приоритета. Они не нужны в префиксных грамматиках. На самом деле этого должно быть достаточно, чтобы решить проблему в любом генераторе парсеров. Какой из них вы используете, BTW?

Кубок имеет конечный вид. Как указывает @rici, двусмысленность в этом случае не может быть решена. Что вы можете сделать, так это ограничить грамматику, так что можно использовать только один последовательный унарный -.

B ::= E 
     | - E 
     ; 
    E ::= + B B 
     | - B B 
     | * B B 
     |/B B 
     | (B) 
     | id 
     | digit 
     ; 

Пожалуйста, проверьте выше несколько раз, так как я довольно ржавый.

+0

Я использую Кубок, а на самом деле мне нужно преимущество, потому что грамматика неоднозначна. Если я не объявляю приоритет, CUP показывает ошибки сдвига/уменьшения. –

+3

@ System.exit: Я боюсь, что приступ не поможет вам с двусмысленностью. Рассмотрим вход ввода, состоящий из токенов 'N''-', а затем токены 'M'' 1'. Для того, чтобы это было выражением, «M-1» токенов '-' должны быть двоичными, а оставшийся« N- (M-1) «унарный», но нет способа определить, какая из них (кроме все они двоичные). Даже если вы произвольно скажете, что первые «N- (M-1)' '-' являются унарными, вы не можете сказать, что такое значение« N- (M-1) », пока вы не прочитаете весь ввод , что означает, что вы не можете разбираться с конечным просмотром. – rici

+0

@rici Ваш комментарий должен быть ответом –