Implementação de um parser descendente recursivo para uma Linguagem Livre de Contexto usando a biblioteca Lark, chamada de MEL.
- Autor: Guilherme Bodart de Oliveira Castro e Ana Carolina Cebin
- Linguagem de programação: Python (versão 3.7.3)
- Ambiente de desenvolvimento: Visual Studio Code (versão 1.33.1) - Windows
- Biblioteca de Parse: Lark
Lark - Texto copiado de "https://lark-parser.readthedocs.io/en/latest/"
Lark pode analisar qualquer gramática livre de contexto.
Lark fornece:
Linguagem de gramática avançada, baseada em EBNF
Três algoritmos de análise para escolher: Earley, LALR (1) e CYK
Construção automática de árvore, inferida da sua gramática
"Fast unicode lexer" com suporte a regexp e contagem automática de linhas
O código de Lark está hospedado no Github: https://github.com/lark-parser/lark
$ pip install lark-parser
LFA-FINALPARSE |_ .vscode |_ launch.json |imagens | src |_ pycache |turtle.cpython-37.pyc | biblioLark.txt |_ TrabalhoFinalLFA.py |_ TrabalhoFinalLFADSL.py |_ grammar.ebnf |_ lfa-trab-final-2019-1.pdf |_ README.md
É o arquivo onde contém a main, as funções e as expressões do Lark;
É o arquivo onde contém a main, e as funções;
É o arquivo onde fica as expressões do Lark usadas no arquivo TrabalhoFinalLFADSL.psy;
sudo apt install python3-tk
cd /usr/src
sudo wget https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz
sudo tar xzf Python-3.7.3.tgz
cd Python-3.7.3
sudo ./configure --enable-optimizations
sudo make altinstall
pip install lark-parser
def main():
while True:
code = input('> ')
try:
run_turtle(code)
except Exception as e:
print(e)
O código acima mostra a main, uma main simples apenas para escrever a expressão e rodar o código principal, o código foi feito pelo autor do Lark no exemplo da DSL Turtle que utilizei
Eu usei este código em vez de um arquivo com várias linhas para serem lidas, porque como é o Turtle ele ficaria desenhando vários desenhos, então preferi fazer vários "testes" pré prontos para serem usados
?start: sttmt
?sttmt : (expr) ";"
?expr : (assign)
| (ifexpr)
| (defun)
| (atom)
| (instruction)+ -> instruction
| (conj)
?instruction: MOVEMENT valor -> movement
| "c" COLOR [COLOR] -> change_color
| "fill" (code_block) -> fill
| "repeat" valor (code_block) -> repeat
| "reset" -> reset
paramlist : ((IDENT)? ("," (IDENT))*)
?defun : "def" (IDENT) "(" (paramlist) ")" (expr)
?ifexpr : "if" (conj) "then" (conj) ("else" (conj))?
?code_block: "{" instruction+ "}"
?conj : (variable|NUMBER) (OPERATOR (variable|NUMBER))*
?rel : OPERATOR
MOVEMENT: "f"
|"b"
|"l"
|"r"
OPERATOR : "=="
| "!="
| ">"
| "=>"
| "<"
| "=<"
?assign : "var"? (variable) "=" (expr)
?atom : "-" (atom)
| "not" (atom)
| "(" (expr) ")"
| NUMBER
| (functioncall)
| (variable)
?functioncall : (IDENT) (arglist)
arglist : "(" ((expr) ("," (expr))*)? ")"
?valor: NUMBER|variable
?variable: (IDENT)
IDENT : LETTER+
COLOR: LETTER+
%import common.LETTER
%import common.INT -> NUMBER
%import common.WS
%ignore WS
Nesta parte do código foi colocado "?" na frente das gramáticas para que fosse resumido o resultado, caso queira ver a árvore mais completa, retirando o ? da frente irá interferir diretamente no Código;
Para buildar/executar o app no ambiente Linux basta abrir o CLI no diretório do MELParser.py e digitar o comando:
python3 LarkPythonParse.py
O python é na versão 3.7.3, não tenho ciência se terá que baixar a nova versão antes, eu apenas testei o programa no ambiente Windowns.
Neste trabalho ainda há vários bugs, porém não consigo dizer exatamente o que, e irei dizer exatamente como que funciona o trabalho, e que tem algumas decisões de projeto, como o if so aceitar números e comparações com ">","<" etc; Apenas uma expressão por linha, não é permitido escrever mais de um sttmt, irá recusar. Outras decisões que explicarei sobre quando falar de cada uma das expressões;
Todo o código fonte está hospedado no meu GitHub.