Analisador Léxico: PDDL

Preâmbulo

O objetivo deste exercício é desenvolver um analisador léxico para um subconjunto da linguagem de descrição Planning Domain Definition Language (PDDL). Seu programa deve receber como argumento dois arquivos: um contendo uma descrição de domínio e outro contendo uma descrição de problema, ambos em PDDL. O programa deve analisar o conteúdo e contar a quantidade de tokens para cada um dos seguintes tipos:

KEYWORD | IDENTIFIER | VARIABLE | NUMBER | ARITHMETIC_OPERATOR | LOGICAL_OPERATOR | QUANTIFIER_OPERATOR | CONDITIONAL_OPERATOR | MODIFIER_OPERATOR | TEMPORAL_OPERATOR | OPTIMIZATION_OPERATOR | DELIMITER | COMMENTS | UNKNOWN

Para um token t, o type(t) é:

A seguir apresenta-se, em pseudocódigo, o protótipo da função isAlphanumeric(t).

function isAlphanumeric(t) {
    while read c; do
        ascii_valur=$(printf "%d" "'$c")
        if ! { 
            ((ascii_value >= 48 && ascii_value <= 57)) ||
            ((ascii_value >= 65 && ascii_value <= 90)) ||
            ((ascii_value >= 97 && ascii_value <= 122)) ||
            ((ascii_value == 45)) || ((ascii_value == 95));                        
        }; then
            return false
        fi
    done < <(grep -o . <<< $t)
    return true
}

Entrada

Seu programa deverá receber como parâmetro dois arquivos de texto nos quais contenham os modelos-fonte de domínio e problema em PDDL a serem analisados.

Saída

O seu programa deverá imprimir, via stdout, a quantidade de tokens, para cada um dos tipos apresentados na seção Preâmbulo, presentes nos arquivos recebidos como parâmetro. O formato de saída deve ser exatamente como mostrado no exemplo abaixo.

Exemplos

Exemplo de entrada

domain.pddl

(define (domain fliaswitch)
	(:requirements :strips)
	(:predicates (switch-is-on) (switch-is-off))
	(:action switch-on
		:parameters ()
		:precondition (switch-is-off)
		:effect (and (switch-is-on) (not (switch-is-off))))
	(:action switch-off
		:parameters ()
		:precondition (switch-is-on)
		:effect (and (switch-is-off) (not (switch-is-on)))))

problem.pddl

(define (problem turn-it-on)
	(:domain fliaswitch)
	(:init (switch-is-off))
	(:goal (switch-is-on)))

Saída para o exemplo acima

KEYWORD: 17
IDENTIFIER: 16
VARIABLES: 0
NUMBER: 0
ARITHMETIC_OPERATOR: 0
LOGICAL_OPERATOR: 4
QUANTIFIER_OPERATOR: 0
CONDITIONAL_OPERATOR: 0
MODIFIER_OPERATOR: 0
TEMPORAL_OPERATOR: 0
OPTIMIZATION_OPERATOR: 0
DELIMITER: 68
COMMENTS: 0
UNKNOWN: 0

Exemplo de entrada

domain.pddl

(define (domain caminhando)
	;; BCR compra dindin na FGA :)
	(:types lugar dindin)
	(:predicates
		(Ligado ?l1 ?l2 - lugar)
		(estou-em ?l - lugar)
		(passei-em ?l - lugar)
		(comprar-dindin ?d - dindin)
		(tem-dindin ?d - dindin)
		(lugar-eh ?l1 ?l2 - lugar))
	(:action mover
		:parameters (?l1 ?l2 - lugar)
		:precondition (and (estou-em ?l1) (or (Ligado ?l1 ?l2) (Ligado ?l2 ?l1)))
		:effect (and (not (estou-em ?l1)) (passei-em ?l2) (estou-em ?l2)
			(not (lugar-eh ?l1 ?l1)) (lugar-eh ?l2 ?l2)))
	(:action comprardindin
		:parameters (?l - lugar ?d - dindin)
		:precondition (and (lugar-eh ?l DindinGourmet) (tem-dindin ?d))
		:effect (and (comprar-dindin ?d) (not (tem-dindin ?d))))
	(:action comprar-todos-dindin
		:parameters (?l - lugar)
		:precondition (and (forall (?d - dindin) (tem-dindin ?d)) (lugar-eh ?l DindinGourmet))
		:effect (forall (?d - dindin) (and (comprar-dindin ?d) 
			(not (tem-dindin ?d)))))
	(:action terremoto
		:parameters ()
		:precondition (forall (?l - lugar) (and (forall (?d - dindin) (and))))
		:effect (forall (?l1 - lugar) (forall (?l2 - lugar)
			(not (Ligado ?l1 ?l2))))))

problem.pddl

(define (problem indoparaobrt)
	(:domain caminhando)
	(:objects S7 CorredorS Escada CorredorI Patio IO-UAC Calcada-UAC Calcada-UED SaidaP1 DindinGourmet SaidaCarro1 SaidaP2 PistaCooper Avenida BrT - lugar
		d1 d2 d3 d4 d5 d6 d7 d8 d9 - dindin)
	(:init
		(Ligado S7 CorredorS)
		(Ligado CorredorS Escada)
		(Ligado Escada CorredorI)
		(Ligado CorredorI Patio)
		(Ligado Patio IO-UAC)
		(Ligado IO-UAC Calcada-UAC)
		(Ligado Calcada-UAC Calcada-UED)
		(Ligado Calcada-UED DindinGourmet)
		(Ligado Calcada-UED SaidaP1)
		(Ligado Calcada-UED SaidaP2)
		(Ligado Calcada-UED SaidaCarro1)
		(Ligado SaidaP1 PistaCooper)
		(Ligado SaidaP2 PistaCooper)
		(Ligado SaidaCarro1 PistaCooper)
		(Ligado PistaCooper Avenida)
		(Ligado Avenida BrT)
		(estou-em S7)
		(lugar-eh S7 S7)
		(passei-em S7)
		(tem-dindin d1)
		(tem-dindin d2)
		(tem-dindin d3)
		(tem-dindin d4)
		(tem-dindin d5)
		(tem-dindin d6)
		(tem-dindin d7)
		(tem-dindin d8)
		(tem-dindin d9)) 
	;; BCR compra TUDO :0
	(:goal (and (estou-em Calcada-UED) (forall (?d - dindin) (not (tem-dindin ?d))) (not (Ligado Calcada-UED SaidaP1)))))

Saída para o exemplo acima

KEYWORD: 26
IDENTIFIER: 156
VARIABLES: 43
NUMBER: 0
ARITHMETIC_OPERATOR: 19
LOGICAL_OPERATOR: 17
QUANTIFIER_OPERATOR: 7
CONDITIONAL_OPERATOR: 0
MODIFIER_OPERATOR: 0
TEMPORAL_OPERATOR: 0
OPTIMIZATION_OPERATOR: 0
DELIMITER: 228
COMMENTS: 2
UNKNOWN: 0

Author: Bruno Ribas e Bruno Ribeiro