Implémenter un langage sur Parrot - partie 9: la syntaxe
Après avoir écrit un tokenizer, avoir produit les unités lexicales et avoir défini une grammaire pour le langage Naam, je passe maintenant à la vérification de la syntaxe.
La vérification de la syntaxe se passe dans la classe Compiler. - C’est pas
le meilleur choix de nom et ça changera par la suite -. Basiquement, cette
classe ne fait que suivre la logique de la grammaire.
class Compiler
# units - Array of LexicalUnits
def compile units
@units = units
program
end
private
def program
while @units.size > 0
case @units.first.type
when :eol then accept(:eol)
else
instruction
end
end
end
def instruction
case @units.first.type
when :keyword then print_statement
when :word then function_def
else
raise Error
end
end
def print_statement
accept(:keyword, 'print')
accept_series(:word, :paro, :int, :parc, :eol)
end
def function_def
accept_series(:word, :paro, :word, :parc, :affect, :eol)
if_clause while if_clause?
else_clause
end
def if_clause
accept(:int)
accept(:keyword, 'if')
test
accept(:eol)
end
def else_clause
accept(:int)
accept(:keyword, 'else')
accept(:eol)
end
def test
accept_series(:word, :op, :int)
end
def accept(type, value = '')
unit = @units.slice!(0)
raise Error unless unit.type == type
if value != ''
raise Error unless unit.value == value
end
end
def accept_series(*args)
args.each {|arg| accept(arg) }
end
def if_clause?
@units[1].type == :keyword && @units[1].value == 'if'
end
endQuelques commentaires sur ce code:
def instruction
# ...
else
raise Error
end
endPlusieurs fois j’utilise la classe Error, qui n’existe pas. C’est parce que
je ne veux pas encore réfléchir à la gestion des erreurs. Les seuls cas qui
m’intéressent pour l’instant sont ceux où ça fonctionne.
def accept(type, value = '')
unit = @units.slice!(0)
raise Error unless unit.type == type
if value != ''
raise Error unless unit.value == value
end
endC’est la méthode accept, toute simple, qui effectue la vérification
de la syntaxe en comparant l’unité lexicale attendue avec celle réellement
disponible. On constate que les unités lexicales (représentées par @units)
sont détruites au fur et à mesure de leur consommation.
La prochaine, il sera enfin temps d’émettre le code PIR.
À demain.