Mudanças entre as edições de "ABNF++: um gerador de parser ABNF"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 21: Linha 21:
 
= Instalação =
 
= Instalação =
  
O compilador ABNF deve ser instalado a partir do seguinte arquivo:
+
O compilador ABNF possui algumas dependências. Instale-as com este comando:<syntaxhighlight lang=bash>
* [http://tele.sj.ifsc.edu.br/~msobral/ptc/abnf/abnfparser_1.0_all.deb abnfparser_1.0_all.deb]
+
sudo apt-get install libpcre++-dev libstdc++-dev g++
 +
</syntaxhighlight>
  
  
Instale-o com o seguinte comando executado em um terminal:
+
O compilador ABNF pode ser instalado como um pacote de software Debian da seguinte forma:
<syntaxhighlight lang=bash>
+
# Faça o download do pacote de software ''abnfparser'': [http://tele.sj.ifsc.edu.br/~msobral/ptc/abnf/abnfparser_1.0_all.deb abnfparser_1.0_all.deb]
 +
# Instale-o com o seguinte comando executado em um terminal:<syntaxhighlight lang=bash>
 
sudo dpkg -i abnfparser_1.0_all.deb
 
sudo dpkg -i abnfparser_1.0_all.deb
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
O compilador ABNF possui algumas dependências. Instale-as com este comando:
+
Opcionalmente, pode-se instalar o compilador ABNF desta forma:
<syntaxhighlight lang=bash>
+
# Faça o download do arquivo .tgz que contém o ''abnfparser'': [http://tele.sj.ifsc.edu.br/~msobral/ptc/abnf/abnfparser-1.0.tgz abnfparser-1.0.tgz]
sudo apt-get install libpcre++-dev libstdc++-dev g++
+
# Descompacte-o em algum diretório com o seguinte comando executado em um terminal:<syntaxhighlight lang=bash>
 +
tar xzf abnfparser-1.0.tgz
 +
</syntaxhighlight>
 +
# Crie um link simbólico para a versão da biblioteca apropriada para o seu sistema: <syntaxhighlight lang=bash>
 +
#!/bin/bash
 +
 
 +
cd lib
 +
rm -f libabnf.a
 +
arch=$(uname -m)
 +
if [ "$arch" = "x86_64" ]; then
 +
  ln -s libabnf64.a libabnf.a
 +
else
 +
  ln -s libabnf32.a libabnf.a
 +
fi
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Edição das 15h05min de 9 de novembro de 2015


O compilador ABNF é um aplicativo desenvolvido no IFSC que gera um parser a partir de uma gramática. O parser se apresenta como uma classe C++ capaz de identificar e decompor texto de entrada de acordo com um conjunto de regras gerado com base na gramática especificada. Por exemplo, ao compilar esta especificação de gramática ABNF:

header="E-mail: " %d60 nome %d62 WSP email CRLF
email=1*16ALPHA %d64 1*8(1*16ALPHA ".") 1*16ALPHA
nome=*6(1*16ALPHA WSP) 1*16ALPHA

... são gerados estes arquivos:

  • parser_default.h: declaração da classe Parser_default
  • parser_default.cpp: implementação da classe Parser_default


A classe Parser_default contém a tabela de regras finais do parser. Uma regra final corresponde a uma linha completa de texto identificada pelo parser, enquanto uma regra intermediária corresponde a um trecho do texto identificado. O parser procura identificar uma regra final que corresponda integralmente a uma linha de texto. No exemplo acima existe uma regra final chamada header e duas regras intermediárias chamadas email e nome. Regras finais sempre terminam com CRLF (a sequência \r\n). Assim, o Parser_default do exemplo consegue identificar apenas linhas de texto que estejam no formato definido pela regra header. Além disso, ele consegue decompô-las em sequências de caracteres dadas pelas regras intermediárias email e nome.

Instalação

O compilador ABNF possui algumas dependências. Instale-as com este comando:

sudo apt-get install libpcre++-dev libstdc++-dev g++


O compilador ABNF pode ser instalado como um pacote de software Debian da seguinte forma:

  1. Faça o download do pacote de software abnfparser: abnfparser_1.0_all.deb
  2. Instale-o com o seguinte comando executado em um terminal:
    sudo dpkg -i abnfparser_1.0_all.deb
    


Opcionalmente, pode-se instalar o compilador ABNF desta forma:

  1. Faça o download do arquivo .tgz que contém o abnfparser: abnfparser-1.0.tgz
  2. Descompacte-o em algum diretório com o seguinte comando executado em um terminal:
    tar xzf abnfparser-1.0.tgz
    
  3. Crie um link simbólico para a versão da biblioteca apropriada para o seu sistema:
    #!/bin/bash
    
     cd lib
     rm -f libabnf.a
     arch=$(uname -m)
     if [ "$arch" = "x86_64" ]; then
       ln -s libabnf64.a libabnf.a
     else
       ln -s libabnf32.a libabnf.a
     fi
    

Uso do compilador

O programa gen_abnf compila uma gramática ABNF, gerando um parser sob medida para a especificação. A execução do compilador sem argumentos, ou com a opção -h, apresenta uma ajuda:

$ gen_abnf 
Uso: /usr/local/bin/gen_abnf [-n name][-d dir] rules_file | -h
-n:	nomeia arquivos de codigo e classe usando "name" (default="default")
-d:	grava arquivos de codigo no subdiretorio "dir"
-h:	mostra esta ajuda
rules_file:	arquivo com regras ABNF

As opções do compilador seguem descritas abaixo em maiores detalhes:

  • -n: especifica o nome do parser a ser criado. O compilador gera um parser chamado Parser_<nome>. Por exemplo, se o nome informado for teste, a classe gerada será Parser_teste.
  • -d: informa o diretório onde devem ser criados os arquivos de código-fonte do parser. Por default é o diretório atual.


A compilação de uma aplicação que use o parser deve seguir as orientações apresentadas pelo gerador do parser. Basicamente devem-se incluir opções de compilação para que o compilador g++ encontre a biblioteca ABNFParser. Essa biblioteca contém a API usada pelo parser. O exemplo a seguir mostra como compilar uma aplicação.

  1. Escreva um arquivo de texto com a gramática ABNF:
    header="E-mail: " nome WSP %d60 email %d62 CRLF
    email=1*16ALPHA %d64 1*8(1*16ALPHA ".") 1*16ALPHA
    nome=1*16ALPHA *3(WSP 1*16ALPHA)
    
  2. Gere o parser usando o programa gen_abnf. Neste exemplo, o parser tem o sufixo teste:
    $ gen_abnf -n teste abnf.txt 
    
    Criou arquivos de codigo "./parser_teste.h" e "./parser_teste.cpp"
    
    Para compilar seu projeto, inclua estas opcoes: "-I/usr/local/include -L/usr/local/lib -labnf -lpcre++"
    
  3. Escreva sua aplicação que usa o parser:
    #include <iostream>
    #include "parser_teste.h"
    
    int main() {
      Parser_teste parser;
    
      ABNFRule * r = (ABNFRule*)parser.match("E-mail: Dona Bilica <bilica@oioio.com.br>\r\n");
      cout << "Nome da regra ativada: " << r->get_name() << endl;
      cout << "Texto que ativou a regra: " << r->get_match() << endl;
    
      Token * email = r->get_token("email");
      Token * nome = r->get_token("nome");
      cout << "Nome: " << nome->get_match() << endl;
      cout << "E-mail: " << email->get_match() << endl;
    }
    
  4. Compile sua aplicação com o compilador g++, passando as opções indicadas no passo 2:
    g++ -o teste teste.cpp parser_teste.cpp -I/usr/local/include -L/usr/local/lib -labnf -lpcre++
    
  5. Execute sua aplicação:
    $ ./teste
    Nome da regra ativada: header
    Texto que ativou a regra: E-mail: Dona Bilica <bilica@oioio.com.br>
    
    Nome: Dona Bilica
    E-mail: bilica@oioio.com.br
    

API do parser

A API do parser ABNF possui as seguintes classes C++:

  • Parser_name: o parser gerado pelo compilador.
  • ABNFParser: classe base para o parser, contendo a interface para seu uso.
  • Token: classe abstrata ancestral de todas as classes de regras a seguir.
  • ABNFSimpleToken: classe que representa uma regra composta por uma string. Esse tipo de regra é ativado quando essa string for idêntica ao início do texto fornecido.
  • ABNFToken: classe que representa uma regra composta por uma expressão regular. Esse tipo de regra é ativado quando essa expressão regular corresponder ao início do texto fornecido.
  • ABNFRule: classe que representa uma sequência de uma ou mais regras quaisquer. Esse tipo de regra é ativado quando cada regra da sequência for ativada sucessivamente com o texto fornecido.
  • ABNFRepRule: classe que representa uma regra qualquer que pode repetir. Esse tipo de regra é ativado quando a regra embutida for ativada repetidamente com o texto fornecido, de acordo com a faixa de repetições especificada.
  • ABNFAltRule: classe que representa um conjunto de regras alternativas. Esse tipo de regra é ativado quando ao menos uma das regras for ativada, de acordo com a faixa de repetições especificada.


Abnf-class.jpg

Classe ABNFParser

Classe Token

Classe ABNFSimpleToken

Classe ABNFToken

Classe ABNFRule

Classe ABNFAltRule

Classe ABNFRepRule

ABNF Core Rules

As regras core ABNF, conforme definidas na RFC 5234, estão predefinidas na API. Elas podem ser referidas diretamente na gramática ABNF:

  • SP: espaço em branco
  • CR: carriage-return (\r)
  • DQUOTE: aspas
  • HTAB: tab (\t)
  • LF: newline (\n)
  • DIGIT: dígito decimal (0 a 9)
  • ALPHA: caractere alfabético (a-z', A-Z)
  • CHAR: caractere ASCII (cód. 0 a 127)
  • CRLF: CR + LF (\r\n)
  • CTL: caractere ASCII de controle (cód. 0 a 31, e também 127)
  • OCTET: um byte qualquer (0 a 255)
  • VCHAR: caractere ASCII visível (cód. 33 a 126)
  • BIT: dígito 0 ou 1
  • HEXDIG: dígito hexadecimal (0-9', A-F)
  • WSP: SP ou HTAB
  • NSP: uma sequência de um ou mais WSP
  • LWSP: zero ou mais CRLF seguido de um WSP