Синтаксический анализ PEG соответствует хотя бы одному порядку сохранения

Учитывая правило PEG:

rule = element1:'abc' element2:'def' element3:'ghi' ;

Как мне переписать это так, чтобы оно соответствовало хотя бы одному из элементов, но, возможно, всем, обеспечивая их порядок?

т.е. Я хотел бы сопоставить все следующие строки:

abc def ghi
abc def
abc     ghi
    def ghi
abc
    def
        ghi

но не пустая строка или неправильно упорядоченные выражения, например. def abc.

Конечно, с тремя элементами я мог бы описать комбинации в отдельных правилах, но по мере увеличения количества элементов это становится подверженным ошибкам.

Есть ли способ указать это в краткой форме?


person ARF    schedule 22.02.2016    source источник


Ответы (2)


Вы можете использовать опции:

rule = [element1:'abc'] [element2:'def'] [element3:'ghi'] ;

Вы должны использовать семантическое действие для rule, чтобы проверить, что хотя бы один токен совпал:

def rule(self, ast):
    if not (ast.element1 or ast.element2 or ast.element3):
        raise FailedSemantics('Expecting at least one token')
    return ast

Другой вариант — использовать несколько вариантов:

rule 
    = 
       element1:'abc' [element2:'def'] [element3:'ghi'] 
    | [element1:'abc']  element2:'def' [element3:'ghi'] 
    | [element1:'abc'] [element2:'def'] element3:'ghi' 
    ;

Кэширование сделает последнее столь же эффективным, как и первое.

Затем вы можете добавить элементы cut для большей эффективности и более содержательных сообщений об ошибках:

rule 
    = 
       element1:'abc' ~  [element2:'def' ~] [element3:'ghi' ~] 
    | [element1:'abc' ~]  element2:'def' ~  [element3:'ghi' ~] 
    | [element1:'abc' ~] [element2:'def' ~] element3:'ghi'  ~
    ;

or:

rule = [element1:'abc' ~] [element2:'def' ~] [element3:'ghi' ~] ;
person Apalala    schedule 22.02.2016
comment
Спасибо за подробное объяснение вариантов. - person ARF; 23.02.2016

Ответ таков: одно предварительное условие на дизъюнкте, а затем последовательность необязательных условий.

rule = &(e1 / e2 / e3) e1? e2? e3?

Это стандартный ПЭГ, где & означает «должен присутствовать, но не потребляться», а ? что означает «необязательный». Большинство синтаксических анализаторов PEG имеют эти функции, если не с этими символами.

person david.pfx    schedule 03.03.2016