Грамматика ANTLR для квазицитатов Scheme

Учитывая следующую грамматику в EBNF:
http://pauillac.inria.fr/cdrom_a_graver/www/bigloo/manual/r5rs-8.html

Приведенная там грамматика квазицитатов не является контекстно-свободной:

<quasiquotation> --> <quasiquotation 1>
<qq template 0> --> <expression>
<quasiquotation D> --> `<qq template D>
       | (quasiquote <qq template D>)
<qq template D> --> <simple datum>
       | <list qq template D>
       | <vector qq template D>
       | <unquotation D>
<list qq template D> --> (<qq template or splice D>*)
       | (<qq template or splice D>+ .  <qq template D>)
       | '<qq template D>
       | <quasiquotation D+1>
<vector qq template D> --> #(<qq template or splice D>*)
<unquotation D> --> ,<qq template D-1>
       | (unquote <qq template D-1>)
<qq template or splice D> --> <qq template D>
       | <splicing unquotation D>
<splicing unquotation D> --> ,@<qq template D-1>
       | (unquote-splicing <qq template D-1>) 

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


person zhujik    schedule 13.06.2011    source источник
comment
D — натуральное число, определяющее «уровни» абстракции. это как правило индуктивной сборки. см. practical-scheme.net/gauche/man/gauche-refe_30.html за хорошее объяснение, а также несколько примеров...   -  person zhujik    schedule 13.06.2011


Ответы (1)


Вы можете добавить параметры как к правилам лексера, так и к правилам парсера, добавив после него [int d], например: foo[int d] : ... ;. Передача параметра 1 правилу foo так же проста, как parse : foo[1];:

Конечно, это не обязательно должен быть int, но может быть любой тип.

Итак, в вашем случае сделайте что-то вроде этого:

quasiquotation
  :  quasiquotationD[1]
  ;

quasiquotationD[int d]
  :  '`' qqTemplate[d]
  |  '(' QUASIQUOTE qqTemplate[d] ')'
  ;

qqTemplate[int d]
  :  (expression)=>  expression
  |  ('(' UNQUOTE)=> unquotation[d]
  |                  simpleDatum
  |                  vectorQQTemplate[d]
  |                  listQQTemplate[d]
  ;

vectorQQTemplate[int d]
  :  '#(' qqTemplateOrSplice[d]* ')'
  ;

listQQTemplate[int d]
  :                     '\'' qqTemplate[d]
  |  ('(' QUASIQUOTE)=> quasiquotationD[d+1]
  |                     '(' (qqTemplateOrSplice[d]+ ('.' qqTemplate[d])?)? ')'
  ;

unquotation[int d]
  :  ',' qqTemplate[d-1]
  |  '(' UNQUOTE qqTemplate[d-1] ')'
  ;

qqTemplateOrSplice[int d]
  :  ('(' UNQUOTE_SPLICING)=> splicingUnquotation[d]
  |                           qqTemplate[d]
  ;

splicingUnquotation[int d]
  :  ',@' qqTemplate[d-1]
  |  '(' UNQUOTE_SPLICING qqTemplate[d-1] ')'
  ;

Обратите внимание, что есть также некоторые синтаксические предикаты, ( ... )=>, для учета некоторых неоднозначностей в грамматике.

Полную версию спецификации R5RS в ANTLR см. в этот ответ.

person Bart Kiers    schedule 14.06.2011