pegjs: как обрабатывать класс символов, которому предшествует более общий класс

У меня есть идентификаторы, которые могут содержать точки, но не в качестве последнего символа. Например, я хотел бы проанализировать date.ymd как идентификатор, но выполнить. как (идентификатор + знак препинания). Регулярное выражение будет ([a-zA-z_][a-zA-Z0-9_.]*[a-zA-Z0-9_])|([a-zA-z_][a-zA-Z0-9_]?) Как я могу это сделать?

Я пытался:

    program = identifier '.'
    identifier = piv:identifierValue {return {type: 'identifier', value: piv};}
    identifierValue
    = $(identifierHeadLetter (identifierTailLetter / '.')* identifierTailLetter*)
    identifierHeadLetter = letter / '_'
    identifierTailLetter "tail character" = letter / digit / '_'
    digit "digit" = '0' / '1' / '2' / '3' / '4' / '5' / '6' / '7' / '8' / '9'
    letter "letter" = 'a' / 'b' / 'c' / 'd' / 'e' / 'f' / 'g' / 'h' / 'i' / 'j' / 'k' / 'l' / 'm' / 'n' / 'o' / 'p' / 'q' / 'r' / 's' / 't' / 'u' / 'v' / 'w' / 'x' / 'y' / 'z' / 'A' / 'B' / 'C' / 'D' / 'E' / 'F' / 'G' / 'H' / 'I' / 'J' / 'K' / 'L' / 'M' / 'N' / 'O' / 'P' / 'Q' / 'R' / 'S' / 'T' / 'U' / 'V' / 'W' / 'X' / 'Y' / 'Z'

но с выполнить. в качестве ввода я получаю: { тип: идентификатор, значение: выполнить.

Если в правиле для идентификатора Value изменить идентификаторTailLetter* на идентификаторTailLetter, я получаю: Строка 1, столбец 9: Ожидается . или завершающий символ, но найден конец ввода.

Я подозреваю, что мой вопрос похож на PegJS - соответствует всем символам, включая ), за исключением случаев, когда ) является последним символом, но я не могу найти аналогичное решение.


person Frans Houweling    schedule 14.04.2021    source источник


Ответы (1)


Я отвечаю себе. Это так же просто, как изменить правило для identifierTailLetter на:

identifierTailLetter "tail character"
 = letter / digit / '_' / ('.' &identifierTailLetter)

Спасибо и извините

person Frans Houweling    schedule 15.04.2021