Skip to content

Latest commit

 

History

History
94 lines (78 loc) · 2.36 KB

aula-31.org

File metadata and controls

94 lines (78 loc) · 2.36 KB

Aula 31

Continuamos a ver o exemplo de como lidar com arquivos CONLL em Lisp. Hoje partimos de onde tínhamos parado na última aula:

(defclass sentence ()
  ((start  :initarg :start
	   :initform 0
	   :accessor sentence-start)
   (tokens :initarg :tokens
	   :initform nil
	   :accessor sentence-tokens)))

(defun read-file (filename)
  (with-open-file (in filename)
    (do ((line (read-line in nil nil)
	       (read-line in nil nil))
	 (lineno 0
		 (+ 1 lineno))
	 (current (make-instance 'sentence))
	 (groups nil))
	((null line)
	 (progn (push current groups)
		(reverse groups)))
      (if (equal line "")
	  (progn (push current groups)
		 (setf current (make-instance 'sentence))
		 (setf (sentence-start current) (+ 1 lineno)))
	  (push line (sentence-tokens current))))))

Conversamos sobre os dois problemas com este código. O primeiro é que se interpretarmos o formato CoNLL-U de forma mais abrangente, queremos que qualquer sequência de uma ou mais linhas em branco delimite sentenças e sentenças são sequências de linhas não brancas. Outro problema com o código acima é que os objetos sentenças criados, instâncias da class sentence, tem as linhas dos tokens invertidas na resposta.

Para resolver este problema, evoluimos para o código que usa a idéia de autômatos como “máquinas de estado”:

(defun read-file (filename)
  (with-open-file (in filename)
    (do ((line (read-line in nil nil)
	       (read-line in nil nil))
	 (lineno 0
		 (+ 1 lineno))
	 (state 1)
	 (tokens nil)
	 (begining 0)
	 (sentences nil))
	((null line)
	 (push (reverse tokens) sentences)
	 (reverse sentences))
      (cond
	((and (equal state 1) (equal line ""))
	 nil)
	((and (equal state 1) (not (equal line "")))
	 (setf state 2
	       begining lineno)
	 (push line tokens))
	((and (equal state 2) (not (equal line "")))
	 (push line tokens))
	((and (equal state 2) (equal line ""))
	 (push (make-instance 'sentence :start begining :tokens (reverse tokens))
	       sentences)
	 (setf state 1
	       tokens nil))))))

Quais os problemas pendentes nesta versão? Como será o output se tentarmos ler um arquivo com:

# key value
alifer
pedro



# key1 valor1 key2 valor2
alexandre
gustavo


Como fazer estas mesmas coisas em Racket?