Interpretação semântica

Este capítulo apresenta o formato de tags de interpretação semântica suportado pela biblioteca de ASR, e fornece detalhes de implementação relevantes, bem como apresenta ferramentas de teste que podem ser utilizadas no desenvolvimento e depuração de gramáticas com interpretação semântica.

A biblioteca de ASR suporta que, nas gramáticas SRGS, sejam inseridas tags de interpretação semântica no formato SISR (Semantic Interpretation for Speech Recognition). Esta seção supõe que o leitor já esteja familiarizado com o padrão SISR. Caso este não seja o caso, recomenda-se consultar a especificação para detalhes da sintaxe adotada e sua semântica correspondente.

O padrão SISR define dois formatos de tags semânticas: o formato literal e o formato em scripts. A biblioteca de ASR suporta ambos os formatos, conforme apresentado nas próximas seções.

Interpretação literal

O formato literal é uma maneira bastante simples de se associar uma cadeia de caracteres a cada sentença reconhecida pela gramática. Devido a sua simplicidade, o formato possui pouca flexibilidade, sendo adequado apenas a gramáticas bastante simples, como listas de comandos ou gramáticas de confirmação.

A fim de se utilizar tags no formato literal em gramáticas ABNF, deve-se utilizar a declaração tag-format no cabeçalho do arquivo de gramática, informando, por meio dela, que o formato adotado será semantics/1.0-literals.

tag-format <semantics/1.0-literals>;

No formato XML, utiliza-se o atributo tag-format do elemento grammar.

<grammar tag-format="semantics/1.0-literals" ...>

Caso uma gramática possua tags de interpretação mas não declare o formato delas no cabeçalho, considera-se que as tags estão no formato literal. Abaixo, segue um exemplo de gramática com tags no formato literal, armazenada no arquivo sim_nao.gram.

#ABNF 1.0 UTF-8;
tag-format <semantics/1.0-literals>;
root $root;
$root = $sim {SIM} | $nao {NAO};
$sim = sim | confirmo | [é] isso [mesmo] | correto;
$nao = não [confirmo] | [está] (errado | incorreto);

A gramática pode ser testada em linha de comando, a partir de um texto de entrada, por meio da ferramenta grammar-parse. A ferramenta recebe como entrada um arquivo de gramática e uma sequência de palavras, e escreve na saída padrão o resultado semântico produzido (caso haja algum), em formato JSON. Abaixo encontram-se alguns exemplos do uso da ferramenta para teste da gramática sim_nao.gram.

$ grammar-parse sim_nao.gram sim
"SIM"
$ grammar-parse sim_nao.gram é isso mesmo
"SIM"
$ grammar-parse sim_nao.gram não
"NAO"
$ grammar-parse sim_nao.gram está incorreto
"NAO"

O resultado aparece na saída padrão entre aspas, pois está no formato JSON.

Interpretação com scripts

A biblioteca de ASR também suporta o formato em scripts definido pela especificação SISR. Para tanto, o formato de tags semantics/1.0 deve ser utilizado nas gramáticas.

tag-format <semantics/1.0>;
<grammar tag-format="semantics/1.0" ...>

Abaixo segue um exemplo de uma gramática de números, utilizando tags em formato script. A gramática, intitulada numeros.gram, reconhece números por extenso entre zero e noventa e nove, e retorna o valor numérico correspondente.

#ABNF 1.0 UTF-8;

tag-format <semantics/1.0>;
root $numero;
$numero = $digito_0_9 | $dezena_10_19 | $dezena_20_90;

$digito_0_9 = zero {out=0} | $digito_1_9;
$digito_1_9 = um {out=1}
              | dois {out=2}
              | três {out=3}
              | quatro {out=4}
              | cinco {out=5}
              | seis {out=6}
              | sete {out=7}
              | oito {out=8}
              | nove {out=9};

$dezena_10_19 = dez {out=10}
                | onze {out=11}
                | doze {out=12}
                | treze {out=13}
                | catorze {out=14}
                | quinze {out=15}
                | dezesseis {out=16}
                | dezessete {out=17}
                | dezoito {out=18}
                | dezenove {out=19};

$dezena_20_90 = vinte {out=20}
                | vinte e $digito_1_9 {out = 20 + rules.latest()}
                | trinta {out=30}
                | trinta e $digito_1_9 {out = 30 + rules.latest()}
                | quarenta {out=40}
                | quarenta e $digito_1_9 {out = 40 + rules.latest()}
                | cinquenta {out=50}
                | cinquenta e $digito_1_9 {out = 50 + rules.latest()}
                | sessenta {out=60}
                | sessenta e $digito_1_9 {out = 60 + rules.latest()}
                | setenta {out=70}
                | setenta e $digito_1_9 {out = 70 + rules.latest()}
                | oitenta {out=80}
                | oitenta e $digito_1_9 {out = 80 + rules.latest()}
                | noventa {out=90}
                | noventa e $digito_1_9 {out = 90 + rules.latest()}
                ;

Gramáticas em formato script também podem ser testadas por meio da ferramenta grammar-parse.

$ grammar-parse numeros.gram vinte e cinco
25
$ grammar-parse numeros.gram quarenta e dois
42

Caso se deseje imprimir valores na tela durante a execução da interpretação semântica, pode-se utilizar a função debug, conforme exemplificado na gramática pizza.gram abaixo.

#ABNF 1.0 UTF-8;

tag-format <semantics/1.0>;
root $root;

$root = [$quero] $quant (pizza | pizzas) [de] $sabor
        {debug("Texto:", meta.quero.text);
        out.quant = rules.quant;
        out.sabor = rules.sabor}
        ;
$quero = [eu] (quero | queria | gostaria de) [uma];
$quant = uma {out=1}
         | duas {out=2}
         | três {out=3}
         | quatro {out=4}
         | cinco {out=5}
         | seis {out=6}
         | sete {out=7}
         | oito {out=8}
         | nove {out=9};
$sabor = escarola {out="ESCAROLA"}
         | marguerita {out="MARGUERITA"}
         | calabresa {out="CALABRESA"};

Abaixo encontram-se alguns exemplos de execução da ferramenta grammar-parse sobre a gramática pizza.gram com algumas sentenças de exemplo.

$ grammar-parse pizza.gram quero uma pizza de calabresa
Texto: quero
{"quant":1,"sabor":"CALABRESA"}

$ grammar-parse pizza.gram gostaria de duas pizzas de escarola
Texto: gostaria de
{"quant":2,"sabor":"ESCAROLA"}

É possível, conforme à especificação SISR, referenciar gramáticas externas em formato literal no corpo de gramáticas em script, e vice-versa.