pt::peg::to::param
ИМЯ
pt::peg::to::param - Преобразование PEG. Запись в формате PARAM
Содержание
КРАТКОЕ ОПИСАНИЕ
package require Tcl 8.5 9
package require pt::peg::to::param ?1.1?
package require pt::peg
package require pt::pe
pt::peg::to::param reset
pt::peg::to::param configure
pt::peg::to::param configure option
pt::peg::to::param configure option value...
pt::peg::to::param convert serial
ОПИСАНИЕ
Не можете разобраться? Возникли трудности с пониманием этого документа? В таком случае ознакомьтесь с обзором в документе Введение в Parser Tools. Этот документ служит отправной точкой для всей системы, частью которой является текущий пакет.
Этот пакет реализует преобразователь грамматик разбора выражений в разметку PARAM.
Он находится в разделе экспорта базового уровня Parser Tools и может использоваться напрямую вместе с другими пакетами этого уровня или опосредованно через менеджер экспорта, предоставляемый пакетом pt::peg::export. Последний предназначен для использования в недоверенных средах и работает через соответствующий плагин экспорта pt::peg::export::param, расположенный между преобразователем и менеджером экспорта.
API
API, предоставляемый этим пакетом, соответствует спецификации API преобразователя, приведённой в спецификации API экспорта Parser Tools.
-
pt::peg::to::param reset
Эта команда сбрасывает конфигурацию пакета к настройкам по умолчанию.
-
pt::peg::to::param configure
Эта команда возвращает словарь с текущей конфигурацией пакета.
-
pt::peg::to::param configure option
Эта команда возвращает текущее значение указанного параметра конфигурации option пакета. Список допустимых параметров приведён в разделе Параметры.
-
pt::peg::to::param configure option value...
Эта команда задаёт указанные значения value для параметров конфигурации option пакета. Список допустимых параметров приведён в разделе Параметры.
-
pt::peg::to::param convert serial
Эта команда принимает каноническую сериализацию грамматики разбора выражений, определённую в разделе Формат сериализации PEG и содержащуюся в serial, и генерирует разметку PARAM, кодирующую грамматику в соответствии с текущей конфигурацией пакета. Созданная строка возвращается в качестве результата команды.
Параметры
Преобразователь в разметку PARAM распознаёт следующие переменные конфигурации и меняет своё поведение в соответствии с их значениями.
-
-template string
Значение этой переменной конфигурации — строка, в которую помещаются сгенерированный текст и остальные параметры конфигурации. Предполагается, что различные места для пользовательских данных обозначаются перечисленными ниже заполнителями. Значение по умолчанию — "@code@".
-
@user@
Заменяется значением переменной конфигурации -user.
-
@format@
Заменяется константой PARAM.
-
@file@
Заменяется значением переменной конфигурации -file.
-
@name@
Заменяется значением переменной конфигурации -name.
-
@code@
Заменяется сгенерированным текстом.
-
-
-name string
Значение этой переменной конфигурации — имя грамматики, для которой выполняется преобразование. Значение по умолчанию — a_pe_grammar.
-
-user string
Значение этой переменной конфигурации — имя пользователя, для которого выполняется преобразование. Значение по умолчанию — unknown.
-
-file string
Значение этой переменной конфигурации — имя файла или другой сущности, из которой получена грамматика, для которой выполняется преобразование. Значение по умолчанию — unknown.
Представление грамматик разбора выражений с помощью кода PARAM
Представление грамматик разбора выражений с помощью кода PARAM — это текст, похожий на ассемблерный, в котором используются инструкции виртуальной машины, описанной в Спецификации машины PackRat, а также несколько дополнительных инструкций для управления потоком выполнения (переход при успехе, переход при ошибке, вызов символа, возврат).
Оно не представляет особой практической ценности и может служить разве что наглядным примером того, как обычно компилируется грамматика, без отвлечения на детали конкретного фреймворка, то есть на поддерживающий код на C и Tcl, генерируемый другими форматами на основе PARAM.
Для него нет отдельной формальной спецификации помимо приведённого выше описания.
Пример
Пусть дана следующая PEG для простых математических выражений
PEG calculator (Expression)
Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ;
Sign <- '-' / '+' ;
Number <- Sign? Digit+ ;
Expression <- Term (AddOp Term)* ;
MulOp <- '*' / '/' ;
Term <- Factor (MulOp Factor)* ;
AddOp <- '+'/'-' ;
Factor <- '(' Expression ')' / Number ;
END;
тогда одним из возможных вариантов сериализации PARAM для неё будет
# -*- text -*-
# Parsing Expression Grammar 'TEMPLATE'.
# Generated for unknown, from file 'TEST'
#
# Grammar Start Expression
#
<<MAIN>>:
call sym_Expression
halt
#
# value Symbol 'AddOp'
#
sym_AddOp:
# /
# '-'
# '+'
symbol_restore AddOp
found! jump found_7
loc_push
call choice_5
fail! value_clear
ok! value_leaf AddOp
symbol_save AddOp
error_nonterminal AddOp
loc_pop_discard
found_7:
ok! ast_value_push
return
choice_5:
# /
# '-'
# '+'
error_clear
loc_push
error_push
input_next "t -"
ok! test_char "-"
error_pop_merge
ok! jump oknoast_4
loc_pop_rewind
loc_push
error_push
input_next "t +"
ok! test_char "+"
error_pop_merge
ok! jump oknoast_4
loc_pop_rewind
status_fail
return
oknoast_4:
loc_pop_discard
return
#
# value Symbol 'Digit'
#
sym_Digit:
# /
# '0'
# '1'
# '2'
# '3'
# '4'
# '5'
# '6'
# '7'
# '8'
# '9'
symbol_restore Digit
found! jump found_22
loc_push
call choice_20
fail! value_clear
ok! value_leaf Digit
symbol_save Digit
error_nonterminal Digit
loc_pop_discard
found_22:
ok! ast_value_push
return
choice_20:
# /
# '0'
# '1'
# '2'
# '3'
# '4'
# '5'
# '6'
# '7'
# '8'
# '9'
error_clear
loc_push
error_push
input_next "t 0"
ok! test_char "0"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 1"
ok! test_char "1"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 2"
ok! test_char "2"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 3"
ok! test_char "3"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 4"
ok! test_char "4"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 5"
ok! test_char "5"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 6"
ok! test_char "6"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 7"
ok! test_char "7"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 8"
ok! test_char "8"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
loc_push
error_push
input_next "t 9"
ok! test_char "9"
error_pop_merge
ok! jump oknoast_19
loc_pop_rewind
status_fail
return
oknoast_19:
loc_pop_discard
return
#
# value Symbol 'Expression'
#
sym_Expression:
# /
# x
# '\('
# (Expression)
# '\)'
# x
# (Factor)
# *
# x
# (MulOp)
# (Factor)
symbol_restore Expression
found! jump found_46
loc_push
ast_push
call choice_44
fail! value_clear
ok! value_reduce Expression
symbol_save Expression
error_nonterminal Expression
ast_pop_rewind
loc_pop_discard
found_46:
ok! ast_value_push
return
choice_44:
# /
# x
# '\('
# (Expression)
# '\)'
# x
# (Factor)
# *
# x
# (MulOp)
# (Factor)
error_clear
ast_push
loc_push
error_push
call sequence_27
error_pop_merge
ok! jump ok_43
ast_pop_rewind
loc_pop_rewind
ast_push
loc_push
error_push
call sequence_40
error_pop_merge
ok! jump ok_43
ast_pop_rewind
loc_pop_rewind
status_fail
return
ok_43:
ast_pop_discard
loc_pop_discard
return
sequence_27:
# x
# '\('
# (Expression)
# '\)'
loc_push
error_clear
error_push
input_next "t ("
ok! test_char "("
error_pop_merge
fail! jump failednoast_29
ast_push
error_push
call sym_Expression
error_pop_merge
fail! jump failed_28
error_push
input_next "t )"
ok! test_char ")"
error_pop_merge
fail! jump failed_28
ast_pop_discard
loc_pop_discard
return
failed_28:
ast_pop_rewind
failednoast_29:
loc_pop_rewind
return
sequence_40:
# x
# (Factor)
# *
# x
# (MulOp)
# (Factor)
ast_push
loc_push
error_clear
error_push
call sym_Factor
error_pop_merge
fail! jump failed_41
error_push
call kleene_37
error_pop_merge
fail! jump failed_41
ast_pop_discard
loc_pop_discard
return
failed_41:
ast_pop_rewind
loc_pop_rewind
return
kleene_37:
# *
# x
# (MulOp)
# (Factor)
loc_push
error_push
call sequence_34
error_pop_merge
fail! jump failed_38
loc_pop_discard
jump kleene_37
failed_38:
loc_pop_rewind
status_ok
return
sequence_34:
# x
# (MulOp)
# (Factor)
ast_push
loc_push
error_clear
error_push
call sym_MulOp
error_pop_merge
fail! jump failed_35
error_push
call sym_Factor
error_pop_merge
fail! jump failed_35
ast_pop_discard
loc_pop_discard
return
failed_35:
ast_pop_rewind
loc_pop_rewind
return
#
# value Symbol 'Factor'
#
sym_Factor:
# x
# (Term)
# *
# x
# (AddOp)
# (Term)
symbol_restore Factor
found! jump found_60
loc_push
ast_push
call sequence_57
fail! value_clear
ok! value_reduce Factor
symbol_save Factor
error_nonterminal Factor
ast_pop_rewind
loc_pop_discard
found_60:
ok! ast_value_push
return
sequence_57:
# x
# (Term)
# *
# x
# (AddOp)
# (Term)
ast_push
loc_push
error_clear
error_push
call sym_Term
error_pop_merge
fail! jump failed_58
error_push
call kleene_54
error_pop_merge
fail! jump failed_58
ast_pop_discard
loc_pop_discard
return
failed_58:
ast_pop_rewind
loc_pop_rewind
return
kleene_54:
# *
# x
# (AddOp)
# (Term)
loc_push
error_push
call sequence_51
error_pop_merge
fail! jump failed_55
loc_pop_discard
jump kleene_54
failed_55:
loc_pop_rewind
status_ok
return
sequence_51:
# x
# (AddOp)
# (Term)
ast_push
loc_push
error_clear
error_push
call sym_AddOp
error_pop_merge
fail! jump failed_52
error_push
call sym_Term
error_pop_merge
fail! jump failed_52
ast_pop_discard
loc_pop_discard
return
failed_52:
ast_pop_rewind
loc_pop_rewind
return
#
# value Symbol 'MulOp'
#
sym_MulOp:
# /
# '*'
# '/'
symbol_restore MulOp
found! jump found_67
loc_push
call choice_65
fail! value_clear
ok! value_leaf MulOp
symbol_save MulOp
error_nonterminal MulOp
loc_pop_discard
found_67:
ok! ast_value_push
return
choice_65:
# /
# '*'
# '/'
error_clear
loc_push
error_push
input_next "t *"
ok! test_char "*"
error_pop_merge
ok! jump oknoast_64
loc_pop_rewind
loc_push
error_push
input_next "t /"
ok! test_char "/"
error_pop_merge
ok! jump oknoast_64
loc_pop_rewind
status_fail
return
oknoast_64:
loc_pop_discard
return
#
# value Symbol 'Number'
#
sym_Number:
# x
# ?
# (Sign)
# +
# (Digit)
symbol_restore Number
found! jump found_80
loc_push
ast_push
call sequence_77
fail! value_clear
ok! value_reduce Number
symbol_save Number
error_nonterminal Number
ast_pop_rewind
loc_pop_discard
found_80:
ok! ast_value_push
return
sequence_77:
# x
# ?
# (Sign)
# +
# (Digit)
ast_push
loc_push
error_clear
error_push
call optional_70
error_pop_merge
fail! jump failed_78
error_push
call poskleene_73
error_pop_merge
fail! jump failed_78
ast_pop_discard
loc_pop_discard
return
failed_78:
ast_pop_rewind
loc_pop_rewind
return
optional_70:
# ?
# (Sign)
loc_push
error_push
call sym_Sign
error_pop_merge
fail! loc_pop_rewind
ok! loc_pop_discard
status_ok
return
poskleene_73:
# +
# (Digit)
loc_push
call sym_Digit
fail! jump failed_74
loop_75:
loc_pop_discard
loc_push
error_push
call sym_Digit
error_pop_merge
ok! jump loop_75
status_ok
failed_74:
loc_pop_rewind
return
#
# value Symbol 'Sign'
#
sym_Sign:
# /
# '-'
# '+'
symbol_restore Sign
found! jump found_86
loc_push
call choice_5
fail! value_clear
ok! value_leaf Sign
symbol_save Sign
error_nonterminal Sign
loc_pop_discard
found_86:
ok! ast_value_push
return
#
# value Symbol 'Term'
#
sym_Term:
# (Number)
symbol_restore Term
found! jump found_89
loc_push
ast_push
call sym_Number
fail! value_clear
ok! value_reduce Term
symbol_save Term
error_nonterminal Term
ast_pop_rewind
loc_pop_discard
found_89:
ok! ast_value_push
return
#
#
Формат сериализации PEG
Здесь описывается формат, используемый Parser Tools для сериализации грамматик разбора выражений в виде неизменяемых значений, предназначенных для передачи, сравнения и т. д.
Мы различаем обычные и канонические сериализации. У PEG может быть несколько обычных сериализаций, но только одна из них будет канонической.
-
обычная сериализация
- Сериализация любой PEG представляет собой вложенный словарь Tcl.
- Этот словарь содержит единственный ключ pt::grammar::peg и соответствующее ему значение. В этом значении содержимое грамматики.
-
Содержимое грамматики представляет собой словарь Tcl, содержащий набор нетерминальных символов и начальное выражение. Значимые ключи и соответствующие им значения:
-
rules
Значение — это словарь Tcl, ключами которого являются имена нетерминальных символов, известных грамматике.
- Каждый нетерминальный символ может встречаться только один раз.
- Пустая строка не является допустимым нетерминальным символом.
-
Значение для каждого символа само является словарём Tcl. Значимые ключи и соответствующие им значения в этом словаре:
+ __is__ The value is the serialization of the parsing expression describing the symbols sentennial structure, as specified in the section [PE serialization format](#section6)\. + __mode__ The value can be one of three values specifying how a parser should handle the semantic value produced by the symbol\. - __value__ The semantic value of the nonterminal symbol is an abstract syntax tree consisting of a single node node for the nonterminal itself, which has the ASTs of the symbol's right hand side as its children\. - __leaf__ The semantic value of the nonterminal symbol is an abstract syntax tree consisting of a single node node for the nonterminal, without any children\. Any ASTs generated by the symbol's right hand side are discarded\. - __void__ The nonterminal has no semantic value\. Any ASTs generated by the symbol's right hand side are discarded \(as well\)\.
-
start
Значение — сериализация начального выражения разбора грамматики, определённая в разделе Формат сериализации PE.
-
Терминальные символы грамматики задаются неявно как множество всех терминальных символов, используемых в начальном выражении и в правых частях правил грамматики.
-
каноническая сериализация
Каноническая сериализация грамматики имеет формат, описанный в предыдущем пункте, и дополнительно удовлетворяет приведённым ниже ограничениям, благодаря которым она является единственной среди всех возможных сериализаций этой грамматики.
- Ключи во всех вложенных словарях Tcl отсортированы в порядке возрастания согласно правилам сортировки словарей, реализованным во встроенной команде Tcl lsort -increasing -dict.
- Строковое представление значения является каноническим представлением словаря Tcl, то есть не содержит лишних пробелов.
Пример
Пусть дана следующая PEG для простых математических выражений
PEG calculator (Expression)
Digit <- '0'/'1'/'2'/'3'/'4'/'5'/'6'/'7'/'8'/'9' ;
Sign <- '-' / '+' ;
Number <- Sign? Digit+ ;
Expression <- Term (AddOp Term)* ;
MulOp <- '*' / '/' ;
Term <- Factor (MulOp Factor)* ;
AddOp <- '+'/'-' ;
Factor <- '(' Expression ')' / Number ;
END;
тогда её каноническая сериализация (без учёта пробелов) будет иметь вид
pt::grammar::peg {
rules {
AddOp {is {/ {t -} {t +}} mode value}
Digit {is {/ {t 0} {t 1} {t 2} {t 3} {t 4} {t 5} {t 6} {t 7} {t 8} {t 9}} mode value}
Expression {is {x {n Term} {* {x {n AddOp} {n Term}}}} mode value}
Factor {is {/ {x {t (} {n Expression} {t )}} {n Number}} mode value}
MulOp {is {/ {t *} {t /}} mode value}
Number {is {x {? {n Sign}} {+ {n Digit}}} mode value}
Sign {is {/ {t -} {t +}} mode value}
Term {is {x {n Factor} {* {x {n MulOp} {n Factor}}}} mode value}
}
start {n Expression}
}
Формат сериализации PE
Здесь описывается формат, используемый Parser Tools для сериализации выражений разбора в виде неизменяемых значений, предназначенных для передачи, сравнения и т. д.
Мы различаем обычные и канонические сериализации. У выражения разбора может быть несколько обычных сериализаций, но только одна из них будет канонической.
-
Обычная сериализация
-
Атомарные выражения разбора
- Строка epsilon является атомарным выражением разбора. Она соответствует пустой строке.
- Строка dot является атомарным выражением разбора. Она соответствует любому символу.
- Строка alnum является атомарным выражением разбора. Она соответствует любому буквенно-цифровому символу Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка alpha является атомарным выражением разбора. Она соответствует любой букве Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка ascii является атомарным выражением разбора. Она соответствует любому символу Unicode с кодом ниже U0080. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка control является атомарным выражением разбора. Она соответствует любому управляющему символу Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка digit является атомарным выражением разбора. Она соответствует любой цифре Unicode. Обратите внимание, что сюда входят символы за пределами диапазона [0..9]. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка graph является атомарным выражением разбора. Она соответствует любому печатному символу Unicode, кроме пробела. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка lower является атомарным выражением разбора. Она соответствует любой строчной букве Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка print является атомарным выражением разбора. Она соответствует любому печатному символу Unicode, включая пробел. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка punct является атомарным выражением разбора. Она соответствует любому знаку пунктуации Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка space является атомарным выражением разбора. Она соответствует любому пробельному символу Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка upper является атомарным выражением разбора. Она соответствует любой прописной букве Unicode. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка wordchar является атомарным выражением разбора. Она соответствует любому символу Unicode, используемому в словах: буквенно-цифровому символу (см. alnum) или символу соединительной пунктуации (например, подчёркиванию). Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка xdigit является атомарным выражением разбора. Она соответствует любой шестнадцатеричной цифре. Это пользовательское расширение PE, основанное на встроенной команде Tcl string is.
- Строка ddigit является атомарным выражением разбора. Она соответствует любой десятичной цифре. Это пользовательское расширение PE, основанное на встроенной команде Tcl regexp.
- Выражение [list t x] является атомарным выражением разбора. Оно соответствует терминальной строке x.
- Выражение [list n A] является атомарным выражением разбора. Оно соответствует нетерминалу A.
-
Составные выражения разбора
- Для выражений разбора e1, e2, ... результат [list / e1 e2 ... ] также является выражением разбора. Это упорядоченный выбор, также называемый приоритетным выбором.
- Для выражений разбора e1, e2, ... результат [list x e1 e2 ... ] также является выражением разбора. Это последовательность.
- Для выражения разбора e результат [list * e] также является выражением разбора. Это замыкание Клини, описывающее ноль или более повторений.
- Для выражения разбора e результат [list + e] также является выражением разбора. Это положительное замыкание Клини, описывающее одно или более повторений.
- Для выражения разбора e результат [list & e] также является выражением разбора. Это предикат просмотра вперёд с AND.
- Для выражения разбора e результат [list ! e] также является выражением разбора. Это предикат просмотра вперёд с NOT.
- Для выражения разбора e результат [list ? e] также является выражением разбора. Это необязательный ввод.
-
-
Каноническая сериализация
Каноническая сериализация выражения разбора имеет формат, описанный в предыдущем пункте, и дополнительно удовлетворяет приведённым ниже ограничениям, благодаря которым она является единственной среди всех возможных сериализаций этого выражения разбора.
- Строковое представление значения является каноническим представлением обычного списка Tcl, то есть не содержит лишних пробелов.
- Терминалы не кодируются как диапазоны, в которых начало и конец совпадают.
Пример
Пусть дано выражение разбора, показанное в правой части правила
Expression <- Term (AddOp Term)*
тогда его каноническая сериализация (без учёта пробелов) будет иметь вид
{x {n Term} {* {x {n AddOp} {n Term}}}}
Ошибки, идеи, отзывы
В этом документе и описываемом в нём пакете, несомненно, есть ошибки и другие проблемы. Сообщайте о них в категории pt на системе отслеживания ошибок Tcllib. Также сообщайте о любых идеях по улучшению пакета и/или документации.
При предложении изменений кода, пожалуйста, предоставляйте унифицированные различия, то есть результат выполнения diff -u.
Кроме того, предпочтительнее прикладывать вложения, а не вставлять исправления в текст сообщения. Чтобы добавить вложение, откройте форму Edit заявки сразу после её создания, а затем воспользуйтесь самой левой кнопкой на дополнительной панели навигации.
КАТЕГОРИЯ
Разбор и грамматики
АВТОРСКИЕ ПРАВА
Авторские права © 2009 Andreas Kupries