Сдвиг уменьшает конфликт

Благодаря Майклу я нашел, где я ошибся. Моя ошибка заключается в том, что Android (Google) не показывает диалоговое окно requestPermission, когда пользователь установил флажок «больше не спрашивать», даже когда вы его программируете. Тогда моей следующей ошибкой было, как я могу получить «ложное» возвращение, зная, что нет разрешения, но android действительно выполняет метод onRequestPermissionsResult, даже если диалог не был показан.

Снова: Спасибо, Майкл

10
задан Caerbanog 12 October 2008 в 21:58
поделиться

6 ответов

Ваше пересмотренное правило ELSEIF не имеет никаких маркеров для условия - оно должно номинально иметь' (' и'), ' добавил.

Более серьезно у Вас теперь есть правило для

elsebody : else
         | elseifs else
         ;

и

elseifs : /* Nothing */
        | elseifs ...something... 
        ;

'Ничто' не не нужно; это неявно заботится о 'elsebody' без 'elseifs'.

Я был бы очень склонен использовать правила 'opt_elseifs ', opt_else' и 'конец':

flow : '#' IF '(' ')' statements opt_elseifs opt_else end
     ;

opt_elseifs : /* Nothing */
            | opt_elseifs '#' ELSIF '(' ')' statements 
            ;

opt_else : /* Nothing */
         | '#' ELSE statements
         ;

end : '#' END
    ;

Я не выполнил это через парсер-генератор, но я нахожу это относительно легким понять.

6
ответ дан 4 December 2019 в 01:58
поделиться

Я думаю, что проблема находится в elseifs пункте.

elseifs : elseifs '#' ELSEIF statements else
        | '#' ELSEIF statements else
        ;

Я думаю, что первая версия не требуется, так как выражение else вернулось к elseifs так или иначе:

else : '#' END
     | '#' ELSE statements '#' END
     | elseifs
     ;

Что происходит, если Вы изменяете elseifs?:

elseifs : '#' ELSEIF statements else
        ;
2
ответ дан 4 December 2019 в 01:58
поделиться

Ответ от Jonathan выше кажется, что это было бы лучшим, но начиная с не работа для Вас у меня есть несколько предложений, которые Вы могли попробовать, который поможет Вам в отладке ошибки.

Во-первых Вы считали создание символа хеша / резкого символа частью самих маркеров (т.е. #END, #IF, и т.д.)? Так, чтобы они были вынуты лексическим анализатором, означая, что они не должны быть включены в синтаксический анализатор.

Во-вторых, я убедил бы Вас переписать правила, не копируя маркерных потоков. (Часть не Повторяет Себя принцип.), Таким образом, правило "'#' Операторы else if еще" должно только существовать в одном месте в том файле (не два, как Вы имеете выше).

Наконец я предлагаю, чтобы Вы изучили приоритет и ассоциативность маркеров IF/ELSEIF/ELSE. Я знаю, что необходимо смочь записать синтаксический анализатор, который не требует этого, но это могла бы быть вещь, в которой Вы нуждаетесь в этом случае.

1
ответ дан 4 December 2019 в 01:58
поделиться

Я все еще переключаю вещь вокруг, и мой исходный вопрос имел некоторые ошибки, так как последовательность elseifs имела еще всегда в конце, который был неправильным. Вот другие, берут в вопросе, на этот раз я добираюсь два, смещают/уменьшают конфликты:

flow : '#' IF '(' ')' statements elsebody 
     ;

elsebody : else 
         | elseifs else
         ;

else : '#' ELSE statements '#' END
     | '#' END
     ;

elseifs : /* empty */
        | elseifs '#' ELSEIF statements
        ;

Конфликты теперь:

// Parser Conflict Information for grammar file "program.y"

Shift/Reduce conflict on symbol "'#'", parser will shift
 Reduce 12: elseifs -> /* empty */
 Shift "'#'":   State-10 -> State-13
  Items for From-state State 10
    7 flow: '#' IF '(' ')' statements . elsebody 
    4 statements: statements . stmt 
  Items for Next-state State 13
    10 else: '#' . ELSE statements '#' END 
    11 else: '#' . END 
    7 flow: '#' . IF '(' ')' statements elsebody 

Shift/Reduce conflict on symbol "'#'", parser will shift
 Reduce 13: elseifs -> elseifs, '#', ELSEIF, statements
 Shift "'#'":   State-24 -> State-6
  Items for From-state State 24
    13 elseifs: elseifs '#' ELSEIF statements .
    -lookahead: '#'
    4 statements: statements . stmt 
  Items for Next-state State 6
    7 flow: '#' . IF '(' ')' statements elsebody 

// End conflict information for parser

Пустые правила просто ухудшают gppg, я боюсь. Но они кажутся настолько естественными для использования, я продолжаю пробовать их.

Я уже знаю, что правая рекурсия решает проблему, как сказала ИНФОРМАЦИЯ 1800 года. Но я ищу решение с левой рекурсией на elseifs пункте.

0
ответ дан 4 December 2019 в 01:58
поделиться

Хорошо - вот грамматика (не минимальна) для если блоки. Я вырыл его из некоторого кода, который я имею (названный для данного случая, на основе hoc от Kernighan & Plauger "Среда программирования UNIX"). Эта грамматика схемы компилирует с Yacc без конфликтов.

%token  NUMBER IF ELSE
%token  ELIF END
%token  THEN
%start program

%%

program
    :   stmtlist
    ;

stmtlist
    :   /* Nothing */
    |   stmtlist stmt
    ;

stmt
    :   ifstmt
    ;

ifstmt
    :   ifcond endif
    |   ifcond else begin
    |   ifcond eliflist begin
    ;

ifcond
    :   ifstart cond then stmtlist
    ;

ifstart
    :   IF
    ;

cond
    :   '(' expr ')'
    ;

then
    :   /* Nothing */
    |   THEN
    ;

endif
    :   END IF begin
    ;

else
    :   ELSE stmtlist END IF
    ;

eliflist
    :   elifblock
    |   elifcond eliflist begin         /* RIGHT RECURSION */
    ;

elifblock
    :   elifcond else begin
    |   elifcond endif
    ;

elifcond
    :   elif cond then stmtlist end
    ;

elif
    :   ELIF
    ;

begin
    :   /* Nothing */
    ;

end
    :   /* Nothing */
    ;

expr
    :   NUMBER
    ;

%%

Я использовал 'ЧИСЛО' в качестве фиктивного элемента вместо ВЕЩЕЙ, и я использовал ELIF вместо ELSEIF. Это включает a ЗАТЕМ но это является дополнительным. 'Начинание' и операции 'конца' использовались для захвата счетчика команд в сгенерированной программе - и поэтому должны быть съемными от этого, не влияя на него.

Была причина, я думал, что должен был использовать правую рекурсию вместо нормальной левой рекурсии - но я думаю, что она относилась к стратегии генерации кода, которую я использовал, а не что-либо еще. Вопросительный знак в комментарии был в оригинале; я не забываю не быть довольным им. Программа в целом работает - это - проект, которым это было на втором месте в течение прошлого десятилетия или так (hmmm... Я сделал некоторую работу в конце 2004 и начала 2005; до этого это были 1992 и 1993).

Я не провел время, работая, почему это компилирует бесконфликтный и что я обрисовал в общих чертах, ранее не делает. Я надеюсь, что это помогает.

0
ответ дан 4 December 2019 в 01:58
поделиться
elsebody : elseifs else
         | elseifs
         ;

elseifs : /* empty */
        | elseifs '#' ELSEIF statements
        ;

else : '#' ELSE statements '#' END
     ;

Я думаю, что это должно оставленный рекурсивно вызывать и всегда завершаться.

0
ответ дан 4 December 2019 в 01:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: