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)
é:
type(t)
= KEYWORD
t
{"define", "domain", "requirements", "types", "constants", "predicates", "functions", "constraints", "action" "parameters", "precondition", "effect", "durative-action", "duration", "condition", "derived", "problem", "objects", "init", "goal", "metric", "total-time", "lenght", "serial", "parallel"}
type(t)
= IDENTIFIER
t
{isAlphanumeric(t)
startsWithLetter(t)}
t
KEYWORD
type(t)
= VARIABLE
t
{? + IDENTIFIER}
type(t)
= NUMBER
t
type(t)
= ARITHMETIC_OPERATOR
t
{+, -, *, /, <, >, =, <=, >=}
type(t)
= LOGICAL_OPERATOR
t
{and, or, not, imply}
type(t)
= QUANTIFIER_OPERATOR
t
{forall, exists}
type(t)
= CONDITIONAL_OPERATOR
t
{when}
type(t)
= MODIFIER_OPERATOR
t
{assign, scale-up, scale-down, increase, decrease}
type(t)
= TEMPORAL_OPERATOR
t
{at, over, start, end}
type(t)
= OPTIMIZATION_OPERATOR
t
{minimize, maximize}
type(t)
= DELIMITER
t
{(, ), :}
type(t)
= COMMENTS
t
{startsWith(t, ";")
endsWith(t, "\n")}
type(t)
= UNKNOWN
t
(KEYWORD
IDENTIFIER
VARIABLE
NUMBER
ARITHMETIC_OPERATOR
LOGICAL_OPERATOR
QUANTIFIER_OPERATOR
CONDITIONAL_OPERATOR
MODIFIER_OPERATOR
TEMPORAL_OPERATOR
OPTIMIZATION_OPERATOR
DELIMITER
COMMENTS)
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
}
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.
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.
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)))
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
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)))))
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