Você está na página 1de 73

UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

PROCESSAMENTO DE ARQUIVOS PGN e FEN PARA DESCRIÇÃO DE JOGOS DE XADREZ

George Henrique Godim da Fonseca


Janniele Aparecida Soares
Graduandos em Sistemas de Informação
Universidade Federal de Ouro Preto - UFOP
Rua 37, 115, B. Loanda – João Monlevade / MG
george@decea.ufop.br / janniele@produtosanchieta.com.br

RESUMO
Este artigo tem como objetivo descrever as funções implementados para o
processamento de arquivos PGN (Portable Game Notation) e FEN ( Forsyth-Edwards
Notation) em Haskell, utilizados normalmente para descrição de jogos de xadrez,
introduzido pelo professor Rodrigo Geraldo Ribeiro como parte das exigências da
disciplina CEA419 - Linguagens de Programação.
PALAVRAS CHAVE. PGN; FEN; Haskell; Xadrez.

ABSTRACT
This paper aims to describe the functions implemented in the development for
processment of files PGN (Portable Game Notation) and FEN ( Forsyth-Edwards
Notation) in Haskell. These files are use normally for describe the game of chess,
introduced by teacher Rodrigo Geraldo Ribeiro as part of the requirements of
discipline CEA419 – Linguagens de Programação.
KEYWORDS. PGN; FEN; Haskell; Chess.
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

1. Introdução
Haskell é uma linguagem de programação pertencente ao paradigma funcional.
Sua estrutura de controle primária são as funções. Em Haskell, uma função é um
mapeamento que leva um ou mais argumentos e produz um único resultado, e é
definida usando uma equação que dá nome à função, um nome para cada um dos seus
argumentos e um corpo que especifica como o resultado pode ser calculado em
termos dos argumentos.
Segue abaixo exemplo de função em Haskell:

double :: Int -> Int


double x = 2 * x

A função double é uma função que recebe um inteiro como parâmetro e retorna o
dobro de seu valor, que também é um inteiro.
Programação funcional pode ser definida como um estilo de programação no qual
o método básico de computação é a aplicação de funções a argumentos. Por sua vez,
linguagem de programação funcional é aquela que se apoia no estilo funcional.
A linguagem de programação Haskell apresenta entre outras, as seguintes
características:

• Programas concisos: Devido à natureza de alto-nível do estilo funcional, em


poucas linhas de código é passado um grande número de instruções.
• Sistema fortemente tipado: Permite que uma grande classe de erros de
incompatibilidade em programas sejam automaticamente detectados antes da sua
execução, através de um sofisticado processo chamado inferência de tipos,
levando a programas mais confiáveis.
• Compreensão de listas: Em Haskell, pode-se construir novas listas selecionando e
filtrando elementos de uma ou mais listas existentes.
• Funções recursivas: Em Haskell, o mecanismo básico pelo qual o looping é
atingido é usando funções recursivas que são definidos em termos de si mesmos.
• Funções de ordem superior: Haskell é linguagem funcional de ordem superior, o
que significa que as funções pode livremente assumir funções como argumentos e
produzem funções como resultados.

No presente artigo será descrito o processamento de arquivo PGN para jogos de


xadrez na linguagem funcional Haskell, proposto pelo professor Rodrigo Geraldo
Ribeiro para afixar os conhecimentos adquiridos sobre a linguagem.
Na seção 2 será descrito o processamento de arquivos, com suas estruturas a
serre desenvolvido, na seção 3, os tipos, instancias e tabelas criadas, na seção 4 , os
parses desenvolvidos, na seção 5, será mostrada algumas funções básicas, na seção 6,
será exibido a entrada e saída, além dos testes realizados, na seção 7 é exibido o
código fonte e na seção 8 o trabalho é concluído.
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

2. Processamento de Arquivos

Os arquivos PGN serão utilizados para que seja possível salvar o progresso do jogo
de xadrez ou para visualizar cada passo da partida descrita no formato.
Para que o processamento do arquivo ocorra precisamos saber a estrutura dos
movimentos no jogo de xadrez, onde temos uma descrição padrão denominada SAN –
Standard Algebraic Notation, um movimento pode ser regular ou especial, os regulares
são descritos por uma seqüência indicando a peça a ser movida, uma seqüência para
evitar ambigüidades entre as peças de uma mesma categoria fornecendo dados sobre
a posição inicial do movimento, é também composta por uma indicação se o
movimento resultou em uma captura, a posição do destino do movimento descrito,
informações sobre uma possível promoção de um peão e finalmente se o movimento
resultou em xeque ou xeque-mate. Existem também dois movimentos especiais
denominados “roque”, onde o rei e uma das torres são movidas simultaneamente, o
roque ao lado da rainha é especificado por O-O-O e o do lado do rei por O-O. As peças
são indicadas por letras maiúsculas de N o cavalo (Knight), B o bispo (Bishop), R a torre
(Rook), Q a rainha (Queen) e K o rei (King), na maioria das vezes as regras do jogo e a
situação do tabuleiro já determinam dada uma posição de destino qual peça esta
sendo movida, mas algumas informações sobre a posição inicial podem ser fornecida
pela coluna (file) que vai de a-h e pela linha (rank) que vai de 1-8 ou uma posição
específica do tabuleiro. A captura é denominada pela letra x e ocorre entre a
especificação de uma ambigüidade e a posição de destino, caso um peão alcance a
linha base do oponente, ele poderá ser promovido para outra peça, indicado pelo
símbolo = e a letra da peça no qual será promovido, quando o movimento resulta um
xeque ou xeque-mate é indicado pelos símbolos + ou # respectivamente.

Abaixo segue a gramática que a compõe:

move -> piece disambiguation capture square promotion check

| O-O-O

| O-O

piece -> N | R | B | Q | K | Lambda

disambiguation -> file | rank | square | Lambda

capture -> x | Lambda

square -> file rank

promotion -> = piece | Lambda


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

check -> + | # | Lambda

file -> a | b | c | d | e | f | g | h

rank -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8

A sintaxe dos arquivos PNG é dada pela gramática livre de contexto abaixo:

pgn -> game pgn | lambda


game -> tags movetext
tags -> tag tags | lambda
tag -> [name value]
name -> symbol
value -> string
movetext ->elements termination
elements -> element elements
| variation elements
| lambda
element -> numopt move nagopt
| lambda
variation -> (elements)
termination -> 1-0
| 0-1
| 1/2-1/2
|*
numopt -> number
| lambda
nagopt -> nag
| lambda
number -> natural dots
dots -> . dots
| lambda
nag ->$ digit *

Definição dos componentes Léxicos

symbol -> (letter j digit)(letter j digit j _ j # j = j : j - j /)_


string -> _ (quoted j char)_ _
quoted -> \char
| \\
|\"
letter -> qualquer letra maiúscula ou minúscula.
digit -> qualquer dígito.
char -> qualquer caractere imprimível exceto " e \
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

A sintaxe dos arquivos FEN é dada pela gramática livre de contexto abaixo:

FEN -> line bar line bar

line bar line bar

line bar line bar

line bar line

next2play castling enpassant halfmove fullmove

line -> choice choice choice choice

choice choice choice choice

choice -> piece | rank | λ

piece -> whitePiece | blackPiece

whitePiece -> K | Q | B | N | R | P

blackPiece -> k | q | b | n | r | p

bar -> /

next2play -> w | b

castling -> kw qw kb pb | -

kw -> K | λ

qw -> Q | λ

kb -> k | λ

qb -> q | λ

enpassant -> square | -

square -> file rank

file -> a | b | c | d | e | f | g | h

rank -> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8

halfmove -> natural


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

fullmove -> natural

3. Tipos, Instâncias e Tabelas de Dados

3.1. Tipos para o movimento

Alguns tipos foram definidos para atender à estrutura do jogo de xadrez que foi
citado no setor 2:

data Move data Piece

data CommonMove data File

data BiggerRoque data Rank

data SmallerRoque data Capture

data Square data Promotion

data Disambiguation data Check

3.2. Tipos para o PGN

Alguns tipos de dados foram definidos para atender à estrutura do PGN:

data Nagopt data PGN

data Nag data Game

data Cifrer data MoveText

data Numopt data Elements

data Number data Variation

data Dots data Element

data Name data LeftChaves

data Value data RightChaves

data Termination data Coments

data Tags

data Tag
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

3.3. Tipos para o FEN

Alguns tipos de dados foram definidos para atender à estrutura do PGN:

data FPiece data FCBlackKing

data FNumber data FCBlackQueen

data FBar data FTrace = FTrace

data FMovesNext data FCastiling

data FCastilingPossibly data FEnPassant

data FCWhiteKing data FHalfmoveClock

data FCWhiteQueen data FFullmoveNumber

3.4. Instâncias de Show para os tipos

Algumas instâncias do show foram criadas para os tipos das estruturas do


xadrez, do PGN e do FEN, cada instancia a baixo retorna uma string referente ao tipo
instanciado:

instance Show Piece instance Show Disambiguation

instance Show File instance Show CommonMove

instance Show Rank instance Show Move

instance Show Capture instance Show Termination

instance Show Promotion instance Show Value

instance Show Check instance Show Name

instance Show BiggerRoque instance Show Tag

instance Show SmallerRoque instance Show Tags

instance Show Square instance Show Dots


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

instance Show Numopt


instance Show FCWhiteKing
instance Show Number
instance Show FCWhiteQueen
instance Show Cifrer
instance Show FCBlackKing
instance Show Nag
instance Show FCBlackQueen
instance Show Nagopt
instance Show FTrace
instance Show PGN
instance Show FCastilingPossibly
instance Show Game
instance Show FCastiling
instance Show MoveText
instance Show FEnPassant
instance Show Elements
instance Show FHalfmoveClock
instance Show Element
instance Show FFullmoveNumber
instance Show FBar
instance Show LeftChaves
instance Show FPiece
instance Show RightChaves
instance Show FNumber
instance Show Coments
instance Show FMovesNext

3.5. Tabelas de representação de tipos

Algumas tabelas foram criadas para representar os tipos das estruturas do


xadrez, do PGN e do FEN, facilitar o desenvolvimento e tornar mais legível o código,
essas tabelas são responsáveis por definir qual tipo é uma determinada string:

tablePiece tableSmallerRoque

tableFile tableTermination

tableRank tableDots

tableCapture tableCifrer

tablePromotion tableLeftChaves

tableCheck tableRightChaves

tableBiggerRoque tableFPiece
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

tableFBar
tableFCWhiteQueen
tableFNumber
tableFCBlackKing
tableFMovesNext
tableFCBlackQueen
tableFCWhiteKing
tableFTrace

4. Parsers Implementados

4.1 Parser referente à estrutura do Xadrez

4.1.1 Parser do Movimento

O parser descrito abaixo, verifica se o tipo do movimento


passado satisfaz a um movimento comum ou a um movimento de
Roque, seja ele ao lado do rei ou ao lado da rainha.

Ele tem dependência com os parser parseCommonMove,


parseBiggerRoque eparseSmaller Roque.

parseMove :: Parser Char Move

parseMove = MMove <$> parseCommonMove <|> MBiggerRoque <$>


parseBiggerRoque <|> MSmallerRoque <$> parseSmallerRoque

4.1.2. Parser Movimento Comum

O parser descrito a baixo define, quais são os tipos que farão a


composição do movimento comum, usamos a notação option pois não é
obrigatório ter o tipo, então quando o parse do tipo desejado não
retorna um tipo o option escolhe o Nothing.

Esse parse possui dependência com o parsePiece,


parseDisambiguation, parseCapture, parseSquare, parsePromotion e
parseCheck

parseCommonMove :: Parser Char CommonMove

parseCommonMove = CommonMove <$> (option parsePiece Nothing)

<*> (option parseDisambiguation Nothing)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

<*> (option parseCapture Nothing)

<*> parseSquare

<*> (option parsePromotion Nothing)

<*> (option parseCheck Nothing)

4.1.3. Parser Peça

O parse para a peça trabalha com nossa tablea de peças, de


acordo com a string passada ele vai retornar para a função o tipo da
peça, onde será utilizada no parse que ocorre a chamada, lembrando
que ele poderá ou não retornar uma peça uma vez que a string não
corresponda a esse tipo.

parsePiece :: Parser Char (Maybe Piece)

parsePiece = choice $ map f tablePiece

where

f (c,p) = const (Just p) <$> token c

4.1.4. Parser Rank

O parse do rank trabalha com nossa tabela de rank, de acordo


com a string passada ele vai retornar para a função o tipo do rank, ou
seja, qual linha a string se refere, que será utilizada no parse onde
ocorre a chamada, lembrando que ele poderá ou não retornar uma linha
uma vez que a string não corresponda a esse tipo.

parseRank :: Parser Char Rank

parseRank = choice $ map f tableRank

where

f (c,p) = const p <$> token c

4.1.5. Parser File


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

O parse do file trabalha com nossa tabela de file, de acordo com


a string passada ele vai retornar para a função o tipo do file, ou seja,
qual coluna a string se refere, que será utilizada no parse onde ocorre a
chamada, lembrando que ele poderá ou não retornar uma coluna uma
vez que a string não corresponda a esse tipo.

parseFile :: Parser Char File

parseFile = choice $ map f tableFile

where

f (c,p) = const p <$> token c

4.1.6. Parser Square

O parse do Square faz a união de uma coluna com uma linha, por
isso ele é dependente dos parses parsFile e parseRank, ou seja, ele
retorna uma posição completa no tabuleiro do xadrez

parseSquare :: Parser Char Square

parseSquare = Square <$> parseFile <*> parseRank

4.1.7. Parser Disambiguation

O parse do disambiguation é dependente dos parses parseFile,


parseRank, e parseSquare, que retornará um desses tipos, a idéia é
evitar ambigüidades entre pessas de uma mesma categoria.

parseDisambiguation :: Parser Char (Maybe Disambiguation)

parseDisambiguation = Just <$> (DFile <$> parseFile <|> DRank <$>


parseRank <|> DSquare <$> parseSquare)

4.1.8. Parser Capture

O parse do Capture trabalha com nossa tabela de capture, de


acordo com a string passada ele vai retornar para a função o tipo do
próprio capture, ou seja, quando a string se referir ao ‘x’ retornará o
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

tipo, que será utilizada no parse onde ocorre a chamada, lembrando que
ele poderá ou não retornar o tipo capture uma vez que a string não
corresponda a esse tipo.

parseCapture :: Parser Char (Maybe Capture)

parseCapture = choice $ map f tableCapture

where

f (c,p) = const (Just p) <$> token c

4.1.9. Parser Promotion

O parse do Promotion trabalha com nossa tabela de promotion,


de acordo com a string passada ele vai retornar para a função o tipo do
promotion, que será utilizada no parse onde ocorre a chamada,
lembrando que ele poderá ou não retornar uma promoção uma vez que
a string não corresponda a esse tipo.

parsePromotion :: Parser Char (Maybe Promotion)

parsePromotion = choice $ map f tablePromotion

where

f (c,p) = const (Just p) <$> token c

4.1.10. Parser Check

O parse do Check trabalha com nossa tabela de check, de acordo


com a string passada ele vai retornar para a função o tipo do check que
ocorreu, no caso xeque simples ou xeque-mate, lembrando que ele
poderá ou não retornar um xeque uma vez que a string não
corresponda a esse tipo.

parseCheck :: Parser Char (Maybe Check)

parseCheck = choice $ map f tableCheck

where
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

f (c,p) = const (Just p) <$> token c

4.1.11. Parser BiggerRoque

O parse do BiggerRoque trabalha com nossa tabela de


biggerRoque, de acordo com a string passada ele vai retornar para a
função o tipo do biggerRoque, que será utilizada no parse onde ocorre a
chamada, lembrando que ele poderá ou não retornar o roque uma vez
que a string não corresponda a esse tipo.

parseBiggerRoque :: Parser Char BiggerRoque

parseBiggerRoque = choice $ map f tableBiggerRoque

where

f (c,p) = const p <$> token c

4.1.12. Parser SmallerRoque

O parse do SmallerRoque trabalha com nossa tabela de


SmallerRoque, de acordo com a string passada ele vai retornar para a
função o tipo do SmallerRoque, que será utilizada no parse onde ocorre
a chamada, lembrando que ele poderá ou não retornar o roque uma vez
que a string não corresponda a esse tipo.

parseSmallerRoque :: Parser Char SmallerRoque

parseSmallerRoque = choice $ map f tableSmallerRoque

where

f (c,p) = const p <$> token c

4.2 Parser referente à estrutura PGN

4.2.1. Parser Tags


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

O parser Tags é dependente do parser parseTag que agrega


várias tipos de tag. A Tags é composto por uma lista de pares do
tipo nome e value.

parseTags :: Parser Char Tags

parseTags = Tags <$> greedy parseTag <*> spaces

4.2.2. Parser Tag

O parser Tag é dependente do parseName e parseVAlue, ele


pega o que esta entre colchetes incluindo o símbolo do colchets. Tags é
composto por uma lista de pares do tipo nome e value.

parseTag :: Parser Char Tag

parseTag = brackets (Tag <$> parseName <*> spaces <*> parseValue


<*> spaces)

where

brackets p = pack (symbol '[') p (symbol ']')

4.2.3. Parser Termination

O parse do Termination trabalha com nossa tabela de


Termination, de acordo com a string passada ele vai retornar para a
função o tipo do Termination, que será utilizada no parse onde ocorre a
chamada, ela sempre retornará um tipo de termination, dependendo da
situação que foi o jogo caso tenha o empate, vitória das peças brancas
ou pretas.

parseTermination :: Parser Char Termination

parseTermination = choice $ map f tableTermination

where

f (c,p) = const p <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.2.4. Parser Value

O parse do Value é dependente do parser parseSymbol, ele irá


retornar um valor do tipo value para agregar informações à partida
através do parser de símbolos, value composto por um tipo de valor,
conhecido com NAG (Numeric Anotation Gly ph) opcional que
indicará algum tipo de informação.

parseValue :: Parser Char Value

parseValue = Value <$> parseString

4.2.5. Parser Name

O parser Name é dependente do parseSymbol e será usado para


compor a tag

parseName :: Parser Char Name

parseName = Name <$> parseSymbol

4.2.6. Parser String

O parser String é responsável por retornar o tipo string

parseString :: Parser Char String

parseString = pack la p la

where

la = symbol '\"'

p = many (quoted <|> char)

quoted = choice $ ((\_ y -> y) <$> symbol '\\' <*> char) : map
symbol "\"\\"

char = satisfy condition

condition c = c `notElem` "\\\""


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.2.7. Parser Dots

O parse do Dots trabalha com nossa tabela de Dots, de acordo


com a string passada ele vai retornar para a função o tipo dot, que será
utilizada no parse onde ocorre a chamada, ela é obrigada a retornar um
tipo dot.

parseDots :: Parser Char Dots

parseDots = choice $ map f tableDots

where

f (c,p) = const p <$> token c

4.2.8. Parser Cifrer

O parse do FCifrer trabalha com nossa tabela de FCifrer, que


retorna o tipo FCifrer caso a string seja o “$” .

parseCifrer :: Parser Char Cifrer

parseCifrer = choice $ map f tableCifrer

where

f (c,p) = const p <$> token c

4.2.9. Parser Nag

O parse do NAG é dependente dos parses parseCifrer e


parseNumber e é referente ao índice da jogada.

parseNag :: Parser Char Nag

parseNag = Nag <$> parseCifrer <*> spaces <*> parseNumber <*>


spaces
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.2.10. Parser Nagopt

O parse do Nagopt é dependente dos parser parseNag, ele


retorna um tipo Nagopt, caso exista o parseNag, caso não ele não é
obrigado a retornar, ele é referente a um possível índice da jogada.

parseNagopt :: Parser Char (Maybe Nagopt)

parseNagopt = Just <$> (Nagopt <$> parseNag <*> spaces)

4.2.11. Parser Natural

O parse do Natural faz a união de vários newDigit, pegando


assim uma seqüência de números ao invés de dígito a dígito.

parseNatural :: Parser Char Int

parseNatural = foldl (\a b -> a * 10 + b) 0 <$> many1 newdigit

4.2.12. Parser Number

O parse do Number é responsável por identificar a partida, ele


verifica se temos uma seqüência de números e se após essa seqüência
existe um ponto. Ele é dependente dos parses parseNatural e
parseDots.

parseNumber :: Parser Char Number

parseNumber = Number <$> parseNatural <*> spaces <*> many


parseDots <*> spaces

4.2.13. Parser Numopt

O parse do Numopt é dependente dos parser parseNumber, ele


retorna um tipo Numopt, caso satisfação a condição, caso não o Maybe
o despresa. O Numopt é um parser para um possível separador de
movimento.

parseNumopt :: Parser Char (Maybe Numopt)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseNumopt = Just <$> (Numopt <$> parseNumber <*> spaces)

4.2.14. Parser Symbol

O parser Symbol verifica se o que foi passado é um símbolo ou


um dígito, e através da função choice ele decide o que vai ser escolhido
e pega vários através do greedy. Pra isso teve que definir a função
isLetter.

parseSymbol = list <$> (letter <|> digit) <*> greedy (choice $ letter :
digit : map symbol "_#=:/")

4.2.15. Parser Element

O parse do Element é dependente do parseNumopt, parseMove


e do parseNagopt. No caso do parseNumopt e parseNagopt, foi usada a
função option pois pode existir ou não existir, já o parseMove é
obrigatório.

parseElement = Variation <$> parens parseElements <|> Element <$>


(option parseNumopt Nothing) <*> spaces <*> parseMove <*> spaces
<*> (option parseNagopt Nothing) <*> spaces <*> (option
parseComents Nothing) <*> spaces

where

parens p = (\ _ y _ -> y) <$> symbol '(' <*> p <*> symbol ')'

4.2.16. Parser Elements

O parse do Elements é dependente da função parseElement e


poderá ter vários tipos Element.

parseElements = greedy parseElement

4.2.17. Parser Espaços em

O parse spaces é responsável por remover espaços em branco.


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

spaces :: Parser Char String

spaces = greedy (satisfy isSpace)

4.2.18. Parser MoveText

O parser MoveText para texto relacionado aos movimentos

parseMoveText = MoveText <$> (Elements <$> parseElements) <*>


parseTermination <*> spaces

4.2.19. Parser Game

O parse Game que é dependente aos parser parseTags,


parseMoveTex

parseGame = Game <$> parseTags <*> spaces <*> parseMoveText <*>


spaces

4.2.20. Parser PGN

O parse PGN, é o parse para leitura do arquivo PGN, que vai


retornar vários jogos

parsePGN = PGN <$> many parseGame <*> spaces

4.2.21. Parser LeftChaves

O parse LeftChaves retorna o tipo de chaves à esquerda

parseLeftChaves :: Parser Char LeftChaves

parseLeftChaves = choice $ map f tableLeftChaves

where

f (c,p) = const p <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.2.22. Parser RightChaves

O parse RightChaves retorna o tipo de chaves à direita

parseRightChaves :: Parser Char RightChaves

parseRightChaves = choice $ map f tableRightChaves

where

f (c,p) = const p <$> token c

4.2.23. Parser Coments

O parse Coments retorna o tipo de comentário, tem


dependência com os parser parseLeftChaves e com o parseRightChaves.

parseComents :: Parser Char (Maybe Coments)

parseComents = Just <$> (Coments <$> parseLeftChaves <*>


parseString <*> parseRightChaves)

4.3 Parser referente à estrutura FEN

4.3.1. Parser FPiece

O parse do FPiece trabalha com nossa tabela de FPiece, que de


acordo com o caracter passado, diferenciado por maiúsculo e
minúsculo, retorna um tipo da peça inclusive com relação à sua cor, se
ela é branca ou preta.

parseFPiece = choice $ map f tableFPiece

where

f (c,p) = const (Just p) <$> token c

4.3.2. Parser FBar

O parse do FBar trabalha com nossa tabela de FBar, que retorna


o tipo FBar caso a string seja o “/” .
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseFBar = choice $ map f tableFBar

where

f (c,p) = const (Just p) <$> token c

4.3.3. Parser FNumber

O parse do FNumber trabalha com nossa tabela de FNumber,


que retorna o tipo FBar caso a string seja o “/” .

parseFNumber = choice $ map f tableFNumber

where

f (c,p) = const (Just p) <$> token c

4.3.4. Parser FMovesNext

O parse do FMovesNext trabalha com nossa tabela de


FMovesNext, de acordo com a string passada ele vai retornar para a
função o tipo do FMovesNext, que será utilizada no parse onde ocorre a
chamada.

parseFMovesNext = choice $ map f tableFMovesNext

where

f (c,p) = const p <$> token c

4.3.5. Parser FTrace

O parse do FTrace trabalha com nossa tabela de FTrace, de


acordo com a string passada ele vai retornar para a função o tipo do
FTrace, que será utilizada no parse onde ocorre a chamada.

parseFTrace = choice $ map f tableFTrace

where

f (c,p) = const p <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.3.6 Parser FCWhiteKing

O parse do FCWhiteKing trabalha com nossa tabela de


FCWhiteKing, de acordo com a string passada ele vai retornar para a
função o tipo do FCWhiteKing, que será utilizada no parse onde ocorre a
chamada.

parseFCWhiteKing = choice $ map f tableFCWhiteKing

where

f (c,p) = const (Just p) <$> token c

4.3.7. Parser FCWhiteQueen

O parse do FCWhiteQueen trabalha com nossa tabela de


FCWhiteQueen, de acordo com a string passada ele vai retornar para a
função o tipo do FCWhiteQueen, que será utilizada no parse onde
ocorre a chamada.

parseFCWhiteQueen = choice $ map f tableFCWhiteQueen

where

f (c,p) = const (Just p) <$> token c

4.3.8. Parser FCBlackKing

O parse do FCBlackKing trabalha com nossa tabela de


FCBlackKing, de acordo com a string passada ele vai retornar para a
função o tipo do FCCBlackKing, que será utilizada no parse onde ocorre
a chamada.

parseFCBlackKing = choice $ map f tableFCBlackKing

where

f (c,p) = const (Just p) <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

4.3.9. Parser FCBlackQueen

O parse do FCBlackQueen trabalha com nossa tabela de


FCBlackQueen, de acordo com a string passada ele vai retornar para a
função o tipo do FCBlackQueen, que será utilizada no parse onde ocorre
a chamada.

parseFCBlackQueen = choice $ map f tableFCBlackQueen

where

f (c,p) = const (Just p) <$> token c

4.3.10. Parser FCastilingPossibly

O parse do FCastilingPossibly, é um parse que depende de outros


parser, tais como parseFCWhiteKing, parseFCWhiteQueen,
parseFCBlackKing, parseFCBlackQueen, ele verifica a possibilidade de ter
algum desses tipos ou não, caso não tenha, através do option ele
retorna Nothing.

parseFCastilingPossibly = FCastilingPossibly <$>

(option parseFCWhiteKing Nothing) <*>

(option parseFCWhiteQueen Nothing) <*>

(option parseFCBlackKing Nothing) <*>

(option parseFCBlackQueen Nothing)

4.3.11. Parser FCastiling

O parse do FCastiling é dependente dos parser


parseFCastilingPossibly, e com a parseFTrace, ele retorna um tipo
FCastiling, caso exista a possibilidade ou caso seja um tipo FCTrace.

parseFCastiling :: Parser Char FCastiling

parseFCastiling = (FCCastilingPossibly <$> parseFCastilingPossibly) <|>


(FCTrace <$> parseFTrace)

4.3.12. Parser FEnPassant


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

O parser do FEnPassant é dependente dos parser parseSquare, e


com a parseFTrace, ele retorna um tipo FEnPassant, caso exista a
possibilidade ou caso seja um tipo FCTrace.

parseFEnPassant :: Parser Char FEnPassant

parseFEnPassant = (FEPSquare <$> parseSquare) <|> (FEPTrace <$>


parseFTrace)

4.3.13. Parser FHalfmoveClock

O parser do FHalfmoveClock para movimentos após último


avanço de peão.

parseFHalfmoveClock = FHalfmoveClock <$> parseNumber

4.3.14. Parser FFullmoveNumber

O parser FFullmoveNumber para Total de Movimentos

parseFFullmoveNumber = FFullmoveNumber <$> parseNumber

4.3.15. Parser spaces

O parser FFullmoveNumber spaces responsável por remover


espaços

spaces :: Parser Char String

spaces = greedy (satisfy isSpace)

5. Funções Desenvolvidas

5.1. Main

Função responsável por ler o arquivo e executar o parseMove passando


a string que recebeu da leitura do arquivo.

main = do
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

(s:_) <- getArgs

content <- readFile s

print (parseMove content)

5.2 Lógica do Promotion

As lógicas abaixo define se relamente o peão poderá ser promovido,


somente se ele tenha chegado à base do oponente, foi implementado dois
promotionCheck para avaliar o lado das peças brancas e o lado das peças
pretas.

promotionCheckWhite :: CommonMove -> Bool

promotionCheckWhite (CommonMove p d c s Nothing k) = True

promotionCheckWhite (CommonMove Nothing d c (Square f Eight) m k) = True

promotionCheckWhite (CommonMove p d c s m k) = False

promotionCheckBlack :: CommonMove -> Bool

promotionCheckBlack (CommonMove p d c s Nothing k) = True

promotionCheckBlack (CommonMove Nothing d c (Square f One) m k) = True

promotionCheckBlack (CommonMove p d c s m k) = False

6. Entradas e Saídas do Programa

Para iniciar o jogo, o usuário deverá executar o arquivo Chess que chamará a
função main, para compilar basta digitar no command do prompt: runghc <nome do
arquivo.hs> <nome do arquivo.pgn> ou digitar :main "nomedoarquvio" que o próprio
programa irá chamar as funções que processarão o arquivo.

6.1. Testes Realizados

Para verificar a corretude do jogo desenvolvido foram utilizados os seguintes


casos de teste:
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

Arquivos

GameWithComments.pgn

Simple.pgn

Comentadas.pgn 4601 linhas (retorno no


arquivo retornoComentado.txt

Tabela 01 - Casos de teste

Todos os casos de teste comportaram de maneira esperada.

7. Código Fonte

O código está dividido em 5 módulos:

• Main

• Move

• PGN

• FEN

• E a biblioteca PARSELIB

Main_________________________________________________________________

module Main where

import System.Environment(getArgs)

import Data.Char

import Prelude hiding (lex)

import ParseLib

import Move
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

import PGN

import FEN

----------------------- Main --------------------------

main = do

(s:_) <- getArgs

content <- readFile s

print (run parseMove content)

------------------------- Logics -------------------------

promotionCheckWhite :: CommonMove -> Bool

promotionCheckWhite (CommonMove p d c s Nothing k) = True

promotionCheckWhite (CommonMove Nothing d c (Square f Eight) m k) = True

promotionCheckWhite (CommonMove p d c s m k) = False

promotionCheckBlack :: CommonMove -> Bool

promotionCheckBlack (CommonMove p d c s Nothing k) = True

promotionCheckBlack (CommonMove Nothing d c (Square f One) m k) = True

promotionCheckBlack (CommonMove p d c s m k) = False

Move_________________________________________________________________

module Move where

import System.Environment(getArgs)

import Data.Char

import Prelude hiding (lex)

import ParseLib
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

----------------------------------------------------------------------

------------------- Estruturas de Dados Utilizadas -------------------

----------------------------------------------------------------------

-- Representação de Movimento

data Move = MMove CommonMove

| MBiggerRoque BiggerRoque

| MSmallerRoque SmallerRoque

deriving(Eq, Ord)

-- Representação de Movimento Comum (sem Roque)

data CommonMove = CommonMove {

piece :: Maybe Piece,

disambiguation :: Maybe Disambiguation,

capture :: Maybe Capture,

square :: Square,

promotion :: Maybe Promotion,

check :: Maybe Check

deriving(Eq, Ord)

-- Representação de "Casa"

data Square = Square File Rank

deriving (Eq, Ord)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Representação de "Casa" de Disambiguidade

data Disambiguation = DFile File

| DRank Rank

| DSquare Square

deriving (Eq, Ord)

-- Representação de Peça

data Piece = King

| Queen

| Rook

| Bishop

| Knight

deriving(Eq, Ord, Enum, Bounded)

-- Representação de Fileira

data File = A

|B

|C

|D

|E

|F

|G

|H

deriving(Eq, Ord, Enum, Bounded)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Representação de Linha

data Rank = One

| Two

| Three

| Four

| Five

| Six

| Seven

| Eight

deriving(Eq, Ord, Enum, Bounded)

-- Rerepsentação de Captura

data Capture = Capture deriving(Eq, Ord, Enum, Bounded)

-- Rerepsentação de Promoção

data Promotion = PromotionQueen

| PromotionKnight

| PromotionRook

| PromotionBishop

deriving(Eq, Ord, Enum, Bounded)

-- Representação de Check

data Check = SimpleCheck

| CheckMate
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

deriving(Eq, Ord, Enum, Bounded)

-- Representação de Roque Maior

data BiggerRoque = BiggerRoque deriving(Eq, Ord, Enum, Bounded)

-- Representação de Roque Menor

data SmallerRoque = SmallerRoque deriving(Eq, Ord, Enum, Bounded)

----------------------------------------------------------------------

---- Tabelas de Strings e suas Estruturas de Dados Correspondentes ---

----------------------------------------------------------------------

-- Tabela de Strings correspondentes a Peças

tablePiece :: [(String, Piece)]

tablePiece = [("K", King),

("Q", Queen),

("R", Rook),

("N", Knight),

("B", Bishop)]

-- Tabela de Strings correspondentes a Fileiras

tableFile :: [(String, File)]

tableFile = [("a", A),

("b", B),

("c", C),

("d", D),
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

("e", E),

("f", F),

("g", G),

("h", H)]

-- Tabela de Strings correspondentes a Linhas

tableRank :: [(String, Rank)]

tableRank = [("1", One),

("2", Two),

("3", Three),

("4", Four),

("5", Five),

("6", Six),

("7", Seven),

("8", Eight)]

-- Tabela de Strings correspondentes a Captura

tableCapture :: [(String, Capture)]

tableCapture = [("x", Capture)]

-- Tabela de Strings correspondentes a Promoção

tablePromotion :: [(String, Promotion)]

tablePromotion = [("=Q", PromotionQueen),

("=N", PromotionKnight),

("=R", PromotionRook),
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

("=B", PromotionBishop)]

-- Tabela de Strings correspondentes a Check

tableCheck :: [(String, Check)]

tableCheck = [("+", SimpleCheck),

("#", CheckMate)]

-- Tabela de Strings correspondentes a Roque Maior

tableBiggerRoque :: [(String, BiggerRoque)]

tableBiggerRoque = [("o-o-o", BiggerRoque)]

-- Tabela de Strings correspondentes a Roque Menor

tableSmallerRoque :: [(String, SmallerRoque)]

tableSmallerRoque = [("o-o", SmallerRoque)]

----------------------------------------------------------------------

----------------------- Parsers Implementados ------------------------

----------------------------------------------------------------------

-- Parser para Movimento

parseMove :: Parser Char Move


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseMove = MMove <$> parseCommonMove <|> MBiggerRoque <$>


parseBiggerRoque <|> MSmallerRoque <$> parseSmallerRoque

-- Parser para Movimento Comum

parseCommonMove :: Parser Char CommonMove

parseCommonMove = CommonMove <$> (option parsePiece Nothing)

<*> (option parseDisambiguation Nothing)

<*> (option parseCapture Nothing)

<*> parseSquare

<*> (option parsePromotion Nothing)

<*> (option parseCheck Nothing)

-- Parser para Peça

parsePiece :: Parser Char (Maybe Piece)

parsePiece = choice $ map f tablePiece

where

f (c,p) = const (Just p) <$> token c

-- Parser para Linha

parseRank :: Parser Char Rank

parseRank = choice $ map f tableRank

where

f (c,p) = const p <$> token c

-- Parser para Fileira


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseFile :: Parser Char File

parseFile = choice $ map f tableFile

where

f (c,p) = const p <$> token c

-- Parser para "Casa"

parseSquare :: Parser Char Square

parseSquare = Square <$> parseFile <*> parseRank

-- Parser para "Casa" de Disambiguidade

parseDisambiguation :: Parser Char (Maybe Disambiguation)

parseDisambiguation = Just <$> (DFile <$> parseFile <|> DRank <$> parseRank <|>
DSquare <$> parseSquare)

-- Parser para Captura

parseCapture :: Parser Char (Maybe Capture)

parseCapture = choice $ map f tableCapture

where

f (c,p) = const (Just p) <$> token c

-- Parser para Promoção (sem validação)

parsePromotion :: Parser Char (Maybe Promotion)

parsePromotion = choice $ map f tablePromotion

where

f (c,p) = const (Just p) <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Parser para Check

parseCheck :: Parser Char (Maybe Check)

parseCheck = choice $ map f tableCheck

where

f (c,p) = const (Just p) <$> token c

-- Parser para Roque Maior

parseBiggerRoque :: Parser Char BiggerRoque

parseBiggerRoque = choice $ map f tableBiggerRoque

where

f (c,p) = const p <$> token c

-- Parser para Roque Menor

parseSmallerRoque :: Parser Char SmallerRoque

parseSmallerRoque = choice $ map f tableSmallerRoque

where

f (c,p) = const p <$> token c

----------------------------------------------------------------------

------------------------ Instâncias de Show --------------------------

----------------------------------------------------------------------

-- Instância de Show Peça

instance Show Piece where


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (King) = "K"

show (Queen) = "Q"

show (Rook) = "R"

show (Knight) = "N"

show (Bishop) = "B"

-- Instância de Show Fileira

instance Show File where

show (A) = "a"

show (B) = "b"

show (C) = "c"

show (D) = "d"

show (E) = "e"

show (F) = "f"

show (G) = "g"

show (H) = "h"

-- Instância de Show Linha

instance Show Rank where

show (One) = "1"

show (Two) = "2"

show (Three) = "3"

show (Four) = "4"

show (Five) = "5"

show (Six) = "6"


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (Seven) = "7"

show (Eight) = "8"

-- Instância de Show Captura

instance Show Capture where

show (Capture) = "x"

-- Instância de Show Promoção

instance Show Promotion where

show (PromotionQueen) = "=Q"

show (PromotionKnight) = "=N"

show (PromotionRook) = "=R"

show (PromotionBishop) = "=B"

-- Instância de Show Check

instance Show Check where

show (SimpleCheck) = "+"

show (CheckMate) = "#"

-- Instância de Show Roque Maior

instance Show BiggerRoque where

show (BiggerRoque) = "o-o-o"

-- Instância de Show Roque Menor

instance Show SmallerRoque where


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (SmallerRoque) = "o-o"

-- Instância de Show "Casa"

instance Show Square where

show (Square f r) = show f ++ show r

-- Instância de Show "Casa" de Disambiguidade

instance Show Disambiguation where

show (DFile f) = show f

show (DRank r) = show r

show (DSquare s) = show s

-- Instância de Show Movimento Comum (sem Roque)

instance Show CommonMove where

show (CommonMove p d c s m k) = maybe "" show p ++

maybe "" show d ++

maybe "" show c ++

show s ++

maybe "" show m ++

maybe "" show k

-- Instância de Show Movimento

instance Show Move where

show (MMove m) = show m

show (MBiggerRoque b) = show b


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (MSmallerRoque s) = show s

PGN___________________________________________________________________

module PGN where

import System.Environment(getArgs)

import Data.Char

import Prelude hiding (lex)

import ParseLib

import Move

----------------------------------------------------------------------

------------------- Estruturas de Dados Utilizadas -------------------

----------------------------------------------------------------------

-- Representação de Arquivo PNG

data PGN = PGN [Game] String

deriving(Eq, Ord)

-- Representação de Jogo

data Game = Game Tags String MoveText String

deriving(Eq, Ord)

-- Representação de Texto de Movimentos

data MoveText = MoveText Elements Termination String


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

deriving(Eq, Ord)

-- Representação de Elementos

data Elements = Elements [Element]

deriving (Ord, Eq)

-- Representação de Elemento (movimento ou (movimento))

data Element = Element {

numopt :: Maybe Numopt,

spaces1 :: String,

move :: Move,

spaces2 :: String,

nagopt :: Maybe Nagopt,

spaces3 :: String,

coments :: Maybe Coments,

spaces4 :: String

| Variation [Element] deriving (Ord, Eq)

data LeftChaves = LeftChaves

deriving (Eq, Ord)

data RightChaves = RightChaves

deriving (Eq, Ord)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

data Coments = Coments LeftChaves String RightChaves

deriving (Eq, Ord)

-- Representação de Passível Índice de Jogada

data Nagopt = Nagopt Nag String

deriving (Eq, Ord)

-- Representação de Índice de Jogada

data Nag = Nag Cifrer String Number String

deriving (Eq, Ord)

-- Representação de Cifrão

data Cifrer = Cifrer

deriving (Eq, Ord)

-- Representação de Possível Separador de Movimento

data Numopt = Numopt Number String

deriving (Eq, Ord)

-- Representação de Separador de Movimento

data Number = Number Int String [Dots] String

deriving (Eq, Ord)

-- Representação de Ponto

data Dots = Dots


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

deriving (Eq, Ord)

-- Representação de Nome

data Name = Name String

deriving (Eq, Ord)

-- Representação de Valor

data Value = Value String

deriving (Eq, Ord)

-- Representação de Resultado

data Termination = WhiteWins

| BlackWins

| Draw

| Unknown

deriving (Eq, Ord)

-- Representação de Tags

data Tags = Tags [Tag] String

deriving (Eq, Ord)

-- Representação de Tag

data Tag = Tag Name String Value String

deriving (Eq, Ord)


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

----------------------------------------------------------------------

---- Tabelas de Strings e suas Estruturas de Dados Correspondentes ---

----------------------------------------------------------------------

-- Tabela de Terminação

tableTermination :: [(String, Termination)]

tableTermination = [("1-0", WhiteWins),

("0-1", BlackWins),

("1/2-1/2", Draw),

("*", Unknown)]

-- Tabela de Ponto

tableDots :: [(String, Dots)]

tableDots = [(".", Dots)]

-- Tabela de Cifrão

tableCifrer :: [(String, Cifrer)]

tableCifrer = [("$", Cifrer)]

-- Tabela de Chaves à Esquerda

tableLeftChaves :: [(String, LeftChaves)]

tableLeftChaves = [("{", LeftChaves)]

-- Tabela de Chaves à Esquerda

tableRightChaves :: [(String, RightChaves)]


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

tableRightChaves = [("}", RightChaves)]

----------------------------------------------------------------------

----------------------- Parsers Implementados ------------------------

----------------------------------------------------------------------

-- Parser para Chaves à Esquerda

parseLeftChaves :: Parser Char LeftChaves

parseLeftChaves = choice $ map f tableLeftChaves

where

f (c,p) = const p <$> token c

-- Parser para Chaves à Direita

parseRightChaves :: Parser Char RightChaves

parseRightChaves = choice $ map f tableRightChaves

where

f (c,p) = const p <$> token c

-- Parser para Chaves à Direita

parseComents :: Parser Char (Maybe Coments)

parseComents = Just <$> (Coments <$> parseLeftChaves <*> parseString <*>


parseRightChaves)

-- Parser para Tags

parseTags :: Parser Char Tags


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseTags = Tags <$> greedy parseTag <*> spaces

-- Parser para Tag

parseTag :: Parser Char Tag

parseTag = brackets (Tag <$> parseName <*> spaces <*> parseValue <*> spaces)

where

brackets p = pack (symbol '[') p (symbol ']')

-- Parser para String

parseString :: Parser Char String

parseString = pack la p la

where

la = symbol '\"'

p = many (quoted <|> char)

quoted = choice $ ((\_ y -> y) <$> symbol '\\' <*> char) : map symbol "\"\\"

char = satisfy condition

condition c = c `notElem` "\\\""

-- Parser para Símbolo

parseSymbol = list <$> (letter <|> digit) <*> greedy (choice $ letter : digit : map symbol
"_#=:/")

-- Função Auxiliar do Parser para Símbolo

letter = satisfy isLetter


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Parser para Resultado

parseTermination :: Parser Char Termination

parseTermination = choice $ map f tableTermination

where

f (c,p) = const p <$> token c

-- Parser para Valor

parseValue :: Parser Char Value

parseValue = Value <$> parseString

-- Parser para Nome

parseName :: Parser Char Name

parseName = Name <$> parseSymbol

-- Parser para Ponto

parseDots :: Parser Char Dots

parseDots = choice $ map f tableDots

where

f (c,p) = const p <$> token c

-- Parser para Cifrão

parseCifrer :: Parser Char Cifrer

parseCifrer = choice $ map f tableCifrer

where

f (c,p) = const p <$> token c


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Parser para Índice de Jogada

parseNag :: Parser Char Nag

parseNag = Nag <$> parseCifrer <*> spaces <*> parseNumber <*> spaces

-- Parser para Possível Índice de Jogada

parseNagopt :: Parser Char (Maybe Nagopt)

parseNagopt = Just <$> (Nagopt <$> parseNag <*> spaces)

-- Parser para Número Natural

parseNatural :: Parser Char Int

parseNatural = foldl (\a b -> a * 10 + b) 0 <$> many1 newdigit

-- Parser para Número

parseNumber :: Parser Char Number

parseNumber = Number <$> parseNatural <*> spaces <*> many parseDots <*> spaces

-- Parser para Possível Separador de Movimento

parseNumopt :: Parser Char (Maybe Numopt)

parseNumopt = Just <$> (Numopt <$> parseNumber <*> spaces)

-- Parser para Elementos

parseElements = greedy parseElement

-- Parser para Elemento


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseElement = Variation <$> parens parseElements <|> Element <$> (option


parseNumopt Nothing) <*> spaces <*> parseMove <*> spaces <*> (option
parseNagopt Nothing) <*> spaces <*> (option parseComents Nothing) <*> spaces

where

parens p = (\ _ y _ -> y) <$> symbol '(' <*> p <*> symbol ')'

-- Parser para Texto Relacionado a Movimentos

parseMoveText = MoveText <$> (Elements <$> parseElements) <*> parseTermination


<*> spaces

-- Paraser para Jogo

parseGame = Game <$> parseTags <*> spaces <*> parseMoveText <*> spaces

-- Parser para Aquivos PGN

parsePGN = PGN <$> many parseGame <*> spaces

-- Parser para Espaços em Branco

spaces :: Parser Char String

spaces = greedy (satisfy isSpace)

----------------------------------------------------------------------

------------------------ Instâncias de Show --------------------------

----------------------------------------------------------------------

instance Show LeftChaves where

show (LeftChaves) = "{"


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

instance Show RightChaves where

show (RightChaves) = "}"

instance Show Coments where

show (Coments lc c rc) = show lc ++ show c ++ show rc

instance Show Termination where

show (WhiteWins) = "1-0"

show (BlackWins) = "0-1"

show (Draw) = "1/2-1/2"

show (Unknown) = "*"

instance Show Value where

show (Value s) = s

instance Show Name where

show (Name n) = n

instance Show Dots where

show (Dots) = "."

instance Show Tag where

show (Tag n s v s2) = "[" ++ show n ++ show s ++ show v ++ "]" ++ show s2


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

instance Show Tags where

show (Tags [] s) = ""

show (Tags (x : xs) s) = show x ++ show xs ++ show s

instance Show Number where

show (Number n s ds s2) = show n ++ show s ++ showDots ds ++ show s2

where

showDots [ ] = ""

showDots (d : ds) = show d ++ showDots


ds

instance Show Numopt where

show (Numopt n s) = show n ++ show s--maybe "" show n

instance Show Cifrer where

show (Cifrer) = "$"

instance Show Nag where

show (Nag c s n s2) = show c ++ show s ++ show n ++ show s2

instance Show Nagopt where

show (Nagopt n s) = show n ++ show s --maybe "" show n

instance Show MoveText where

show (MoveText e t s) = show e ++ show t ++ show s


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

instance Show Element where

show (Element numopt s1 move s2 nagopt s3 coments s4) = maybe "" show numopt
++

show s1 ++

show move ++

show s2 ++

maybe "" show nagopt ++

show s3 ++

maybe "" show coments ++

show s4

instance Show Elements where

show (Elements (x : xs)) = show x ++ show xs

instance Show Game where

show (Game t s m s2) = show t ++ show s ++ show m ++ show s2

instance Show PGN where

show (PGN [] s) = ""

show (PGN (x : xs) s) = show x ++ show xs ++ show s


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

FEN___________________________________________________________________

module FEN where

import System.Environment(getArgs)

import Data.Char

import Prelude hiding (lex)

import ParseLib

import Move

import PGN

----------------------------------------------------------------------

------------------- Estruturas de Dados Utilizadas -------------------

----------------------------------------------------------------------

-- Representação de Peças

data FPiece = BKing

| WKing

| BQueen

| WQueen

| BBishop

| WBishop

| BKnight

| WKnight

| BRook

| WRook
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

| BPawn

| WPawn

deriving (Eq, Ord)

-- Representação de Números (casas vazias em uma linha)

data FNumber = FOne

| FTwo

| FThree

| FFour

| FFive

| FSix

| FSeven

| FEight

deriving(Eq, Ord, Enum, Bounded)

-- Representação de Barra

data FBar = FBar

deriving (Eq, Ord)

-- Representação de Próximo a Movimentar

data FMovesNext = FBlackMovesNext

| FWhiteMovesNext

deriving (Eq, Ord)

-- Representação de Prossibilidade de Roque


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

data FCastilingPossibly = FCastilingPossibly {

fcwhiteking :: Maybe FCWhiteKing,

fcwhitequeen :: Maybe FCWhiteQueen,

fcblackking :: Maybe FCBlackKing,

fcblackqueen :: Maybe FCBlackQueen

deriving(Eq, Ord)

-- Representação de Roque Possível no lado do Rei Branco

data FCWhiteKing = FCWhiteKing

deriving (Eq, Ord)

-- Representação de Roque Possível no lado da Rainha Branca

data FCWhiteQueen = FCWhiteQueen

deriving (Eq, Ord)

-- Representação de Roque Possível no lado do Rei Preto

data FCBlackKing = FCBlackKing

deriving (Eq, Ord)

-- Representação de Roque Possível no lado da Rainha Preta

data FCBlackQueen = FCBlackQueen

deriving (Eq, Ord)

-- Representação de Traço
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

data FTrace = FTrace

deriving (Eq, Ord)

-- Representação de Roque

data FCastiling = FCCastilingPossibly FCastilingPossibly

| FCTrace FTrace

-- Representação de En Passant

data FEnPassant = FEPSquare Square

| FEPTrace FTrace

-- Representação de Movimentos após último avanço de peão

data FHalfmoveClock = FHalfmoveClock Number

deriving (Eq, Ord)

-- Representação do Total de Movimentos

data FFullmoveNumber = FFullmoveNumber Number

deriving (Eq, Ord)

{-

data FFile = [FPiece]

deriving (Eq, Ord)

data FEN = FEN {


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

row1 :: FFile,

trace1 :: FTrace,

row2 :: FFile,

trace2 :: FTrace,

row3 :: FFile,

trace3 :: FTrace,

row4 :: FFile,

trace4 :: FTrace,

row5 :: FFile,

trace5 :: FTrace,

row6 :: FFile,

trace6 :: FTrace,

row7 :: FFile,

trace7 :: FTrace,

row8 :: FFile,

enpassant :: FEnPassant,

halfmove :: FHalfNumberMove,

fullmove :: FFullmoveNumber

deriving(Eq, Ord)

-}

----------------------------------------------------------------------

---- Tabelas de Strings e suas Estruturas de Dados Correspondentes ---

----------------------------------------------------------------------
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Tabela de Peça

tableFPiece :: [(String, FPiece)]

tableFPiece = [("k", BKing),

("K", WKing),

("q", BQueen),

("Q", WQueen),

("b", BBishop),

("B", WBishop),

("n", BKnight),

("N", WKnight),

("r", BRook),

("R", WRook),

("p", BPawn),

("P", WPawn)]

-- Tabela de Barra

tableFBar :: [(String, FBar)]

tableFBar = [("/", FBar)]

-- Tabela de Número

tableFNumber :: [(String, FNumber)]

tableFNumber = [("1", FOne),

("2", FTwo),

("3", FThree),

("4", FFour),
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

("5", FFive),

("6", FSix),

("7", FSeven),

("8", FEight)]

-- Tabela de Próximo a Mover

tableFMovesNext :: [(String, FMovesNext)]

tableFMovesNext = [("w", FWhiteMovesNext),

("b", FBlackMovesNext)]

-- Tabela de Roque Possível no lado do Rei Branco

tableFCWhiteKing :: [(String, FCWhiteKing)]

tableFCWhiteKing = [("K", FCWhiteKing)]

-- Tabela de Roque Possível no lado da Rainha Branca

tableFCWhiteQueen :: [(String, FCWhiteQueen)]

tableFCWhiteQueen = [("Q", FCWhiteQueen)]

-- Tabela de Roque Possível no lado do Rei Preto

tableFCBlackKing :: [(String, FCBlackKing)]

tableFCBlackKing = [("k", FCBlackKing)]

-- Tabela de Roque Possível no lado da Rainha Preta

tableFCBlackQueen :: [(String, FCBlackQueen)]

tableFCBlackQueen = [("q", FCBlackQueen)]


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Tabela de Traço

tableFTrace :: [(String, FTrace)]

tableFTrace = [("-", FTrace)]

----------------------------------------------------------------------

----------------------- Parsers Implementados ------------------------

----------------------------------------------------------------------

-- Parser para Peça

parseFPiece = choice $ map f tableFPiece

where

f (c,p) = const (Just p) <$> token c

-- Parser para Barra

parseFBar = choice $ map f tableFBar

where

f (c,p) = const (Just p) <$> token c

-- Parser para Número

parseFNumber = choice $ map f tableFNumber

where

f (c,p) = const (Just p) <$> token c

-- Parser para Próximo a Movimentar


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseFMovesNext = choice $ map f tableFMovesNext

where

f (c,p) = const p <$> token c

-- Parser para Traço

parseFTrace = choice $ map f tableFTrace

where

f (c,p) = const p <$> token c

-- Parser para Roque Possível no lado do Rei Branco

parseFCWhiteKing = choice $ map f tableFCWhiteKing

where

f (c,p) = const (Just p) <$> token c

-- Parser para Roque Possível no lado da Rainha Branca

parseFCWhiteQueen = choice $ map f tableFCWhiteQueen

where

f (c,p) = const (Just p) <$> token c

-- Parser para Roque Possível no lado do Rei Preto

parseFCBlackKing = choice $ map f tableFCBlackKing

where

f (c,p) = const (Just p) <$> token c

-- Parser para Roque Possível no lado da Rainha Preta


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

parseFCBlackQueen = choice $ map f tableFCBlackQueen

where

f (c,p) = const (Just p) <$> token c

-- Parser para Possibilidade de Roque

parseFCastilingPossibly = FCastilingPossibly <$> (option parseFCWhiteKing Nothing)


<*>

(option parseFCWhiteQueen Nothing) <*>

(option parseFCBlackKing Nothing) <*>

(option parseFCBlackQueen Nothing)

-- Parser para Roque

parseFCastiling :: Parser Char FCastiling

parseFCastiling = (FCCastilingPossibly <$> parseFCastilingPossibly) <|> (FCTrace <$>


parseFTrace)

-- Parser para En Passant

parseFEnPassant :: Parser Char FEnPassant

parseFEnPassant = (FEPSquare <$> parseSquare) <|> (FEPTrace <$> parseFTrace)

-- Parser para Movimentos após último avanço de peão

parseFHalfmoveClock = FHalfmoveClock <$> parseNumber

-- Parser para Total de Movimentos

parseFFullmoveNumber = FFullmoveNumber <$> parseNumber


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

-- Parser para Espaços em Branco

spaces :: Parser Char String

spaces = greedy (satisfy isSpace)

----------------------------------------------------------------------

------------------------ Instâncias de Show --------------------------

----------------------------------------------------------------------

-- Instância de Show Peça

instance Show FPiece where

show (BKing) = "k"

show (WKing) = "K"

show (BQueen) = "q"

show (WQueen) = "Q"

show (BBishop) = "b"

show (WBishop) = "B"

show (BKnight) = "n"

show (WKnight) = "N"

show (BRook) = "r"

show (WRook) = "R"

show (BPawn) = "p"

show (WPawn) = "P"

-- Instância de Show Barra


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

instance Show FBar where

show (FBar) = "/"

-- Instância de Show Número

instance Show FNumber where

show (FOne) = "1"

show (FTwo) = "2"

show (FThree) = "3"

show (FFour) = "4"

show (FFive) = "5"

show (FSix) = "6"

show (FSeven) = "7"

show (FEight) = "8"

-- Instância de Show Próximo a Movimentar

instance Show FMovesNext where

show (FWhiteMovesNext) = "w"

show (FBlackMovesNext) = "b"

-- Instância de Show Roque Possível no lado do Rei Branco

instance Show FCWhiteKing where

show (FCWhiteKing) = "K"

-- Instância de Show Roque Possível no lado da Rainha Branca

instance Show FCWhiteQueen where


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (FCWhiteQueen) = "Q"

-- Instância de Show Roque Possível no lado do Rei Preta

instance Show FCBlackKing where

show (FCBlackKing) = "k"

-- Instância de Show Roque Possível no lado da Rainha Preta

instance Show FCBlackQueen where

show (FCBlackQueen) = "q"

-- Instância de Show Traço

instance Show FTrace where

show (FTrace) = "-"

-- Instância de Show Possibilidade De Roque

instance Show FCastilingPossibly where

show (FCastilingPossibly wk wq bk bq) = maybe "" show wk ++

maybe "" show wq ++

maybe
"" show bk ++

maybe ""
show bq

-- Instância de Show Roque

instance Show FCastiling where


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

show (FCCastilingPossibly c) = show c

show (FCTrace t) = show t

-- Instância de Show En Passant

instance Show FEnPassant where

show (FEPSquare s) = show s

show (FEPTrace t) = show t

-- Instância de Show Movimentos após último avanço de peão

instance Show FHalfmoveClock where

show (FHalfmoveClock n) = show n

-- Instância de Total de Movimentos

instance Show FFullmoveNumber where

show (FFullmoveNumber n) = show n

BIBLIOTECA PARSELIB_____________________________________________________

module ParseLib where

import Char

infixl 7 <$>

infixl 6 <*>

infixr 4 <|>

-- The type of parsers


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

type Parser symbol result = [symbol] -> [(result,[symbol])]

-- running a parser

run :: (Show result, Show symbol) => Parser symbol result -> [symbol] -> result

run p xs = case p xs of

((x,[]):_) -> x

y -> error $ show y

-- Elementary parsers

symbol :: Eq s => s -> Parser s s

symbol a [] = []

symbol a (x:xs) | x == a = [(x,xs)]

| otherwise = []

satisfy :: (s -> Bool) -> Parser s s

satisfy p [] = []

satisfy p (x:xs) | p x = [(x,xs)]

| otherwise = []

token :: Eq s => [s] -> Parser s [s]

token k xs | k == take n xs = [(k,drop n xs)]

| otherwise = []
UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

where n = length k

failp :: Parser s a

failp xs = []

succeed :: a -> Parser s a

succeed r xs = [(r,xs)]

-- Applications of elementary parsers

digit :: Parser Char Char

digit = satisfy isDigit

-- Parser combinators

(<|>) :: Parser s a -> Parser s a -> Parser s a

(p <|> q) xs = p xs ++ q xs

(<*>) :: Parser s (b -> a) -> Parser s b -> Parser s a

(p <*> q) xs = [(f x,zs)

|(f ,ys) <- p xs

,( x,zs) <- q ys

(<$>) :: (a -> b) -> Parser s a -> Parser s b


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

(f <$> p) xs = [(f y,ys)

|( y,ys) <- p xs

-- Applications of parser combinators

newdigit :: Parser Char Int

newdigit = f <$> digit

where f c = ord c - ord '0'

-- EBNF parser combinators

option :: Parser s a -> a -> Parser s a

option p d = p <|> succeed d

many :: Parser s a -> Parser s [a]

many p = list <$> p <*> many p <|> succeed []

many1 :: Parser s a -> Parser s [a]

many1 p = list <$> p <*> many p

pack :: Parser s a -> Parser s b -> Parser s c -> Parser s b

pack p r q = pi32 <$> p <*> r <*> q

listOf :: Parser s a -> Parser s b -> Parser s [a]


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

listOf p s = list <$> p <*> many (pi22 <$> s <*> p)

-- Auxiliary functions

determ :: Parser s b -> Parser s b

determ p xs | null r = []

| otherwise = [head r]

where r = p xs

greedy, greedy1 :: Parser s b -> Parser s [b]

greedy = determ . many

greedy1 = determ . many1

list x xs = x:xs

pi22 x y = y

pi32 x y z = y

-- Applications of EBNF combinators

natural :: Parser Char Int

natural = foldl (\a b -> a*10 + b) 0 <$> many1 newdigit

integer :: Parser Char Int

integer = (const negate <$> (symbol '-')) `option` id <*> natural


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

identifier :: Parser Char String

identifier = list <$> satisfy isAlpha <*> greedy (satisfy isAlphaNum)

parenthesised p = pack (symbol '(') p (symbol ')')

commaList :: Parser Char a -> Parser Char [a]

commaList p = listOf p (symbol ',')

-- Chain expression combinators

chainr :: Parser s a -> Parser s (a -> a -> a) -> Parser s a

chainr pe po = h <$> many (j <$> pe <*> po) <*> pe

where j x op = (x `op`)

h fs x = foldr ($) x fs

chainl :: Parser s a -> Parser s (a -> a -> a) -> Parser s a

chainl pe po = h <$> pe <*> many (j <$> po <*> pe)

where j op x = (`op` x)

h x fs = foldl (flip ($)) x fs

-- Combinators for repetition

psequence :: [Parser s a] -> Parser s [a]


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

psequence [] = succeed []

psequence (p:ps) = list <$> p <*> psequence ps

psequence' :: [Parser s a] -> Parser s [a]

psequence' = foldr f (succeed [])

where f p q = list <$> p <*> q

choice :: [Parser s a] -> Parser s a

choice = foldr (<|>) failp


UNIVERSIDADE FEDERAL DE OURO PRETO

Campus João Monlevade

8. Considerações finais

O trabalho proposto pelo professor Rodrigo Geraldo Ribeiro atingiu seu objetivo,
visto que, através dele foi adquirida uma gama de informações enormes, inclusive
sobre parser e definição de tipos de dados em Haskeel. Para desenvolver o que foi
proposto, teve-se que exercitar a manipulação de parser, entrada e saída, criação de
tipos de dados com gramáticas livres de contexto, uso de funções da biblioteca,
funções de ordem superior, estruturas de repetição e a lógica de programação em
Haskell.

No desenvolvimento para o processamento do arquivo, pôde-se também observar


importantes características da linguagem programação Haskell, como
desenvolvimento de programas concisos, sistema fortemente tipados, funções
recursivas e funções de ordem superior.

9. Referência Bibliográfica

HUTTON, Ghaham. Programming in Haskell. University of Nottingham, 2007.

Você também pode gostar