Created
March 18, 2013 18:18
-
-
Save pabloDon/5189460 to your computer and use it in GitHub Desktop.
Compilador de textos para proyecto ToR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Compiler | |
def self.compile doc | |
puts "INICIO COMPILACION" | |
tokens = compile_documento doc | |
puts "FIN COMPILACION" | |
if tokens[0] != :error | |
puts "INICIO SINTACTICO" | |
tokens = syntax_doc tokens | |
puts "FIN SINTACTICO" | |
if tokens[0] != :error | |
puts "INICIO COMPILACION" | |
tokens = compile_doc tokens | |
puts "FIN COMPILACION" | |
else | |
return tokens | |
end | |
else | |
return tokens | |
end | |
end | |
# ----- ANALISIS MORFOLOGICO ----- | |
def self.compile_documento doc | |
retorno = [] | |
puts "DOCUMENTO: #{doc}" | |
doc.split(/\n/).each do |linea| | |
comp = compile_linea linea | |
puts "PROCESANDO: #{linea} - #{comp}" | |
if comp[0] != :error and comp.size > 0 | |
retorno = retorno + [comp] | |
else | |
return [:error] | |
end | |
end | |
return retorno | |
end | |
# Opciones disponibles: | |
# * PROYECTO | |
# - TAREA | |
# @attr ATRIBUTO | |
# DESCRIPCION | |
def self.compile_linea linea | |
retorno = case linea | |
when /\s*\*.*/ then compile_proj linea | |
when /\s*\@.*/ then compile_attr linea | |
when /\s*\-.*/ then compile_task linea | |
when /\s*[a-zA-Z].*/ then compile_descr linea | |
when /\s*/ then [] | |
else [:error] | |
end | |
return retorno | |
end | |
# * PROYECTO | |
def self.compile_proj linea | |
i = 0 | |
if linea[0] == "*" | |
i = 1 | |
#whitespaces | |
while i <= linea.size and linea[i] == " " do | |
i = i + 1 | |
end | |
if linea.size == i | |
return [:error] | |
end | |
return [:proj, linea[i...linea.size]] | |
else | |
return [:error] | |
end | |
end | |
# @attr ATRIBUTO | |
def self.compile_attr linea | |
if linea[0] == "@" | |
if linea[1] and linea[1].match /[a-zA-Z].*/ | |
atr = "" | |
i = 1 | |
#attr | |
while i < linea.size and linea[i] != " " do | |
atr = atr + linea[i] | |
i = i + 1 | |
end | |
#whitespaces | |
while i < linea.size and linea[i] == " " do | |
i = i + 1 | |
end | |
if linea.size == i | |
return [:error] | |
else | |
valor = "" | |
#ATRIBUTO | |
while i < linea.size and linea[i] != " " do | |
puts "#{i} - #{linea[i]}" | |
valor = valor + linea[i] | |
i = i + 1 | |
end | |
return [:attr, {:attr => atr, :valor => valor}] | |
end | |
else | |
return [:error] | |
end | |
else | |
return [:error] | |
end | |
end | |
# - TASK | |
def self.compile_task linea | |
if linea[0] == "-" | |
i = 1 | |
#whitespaces | |
while i <= linea.size and linea[i] == " " do | |
i = i + 1 | |
end | |
if linea.size == i | |
return [:error] | |
end | |
return [:task, linea[i...linea.size]] | |
else | |
return [:error] | |
end | |
end | |
# DESCRIPCION | |
def self.compile_descr linea | |
return [:desc, linea] | |
end | |
# ----- ANALISIS SINTACTICO ----- | |
def self.syntax_doc tokens | |
return syntax_by_token tokens, :idle, 0 | |
end | |
#Analizamos que el transito de tokens sea correcto (Simplemente queremos que no inicie el texto con attr o desc) | |
def self.syntax_by_token tokens, stat, num_token | |
if tokens.size == num_token | |
return tokens | |
end | |
token = tokens[num_token] | |
if stat == :idle | |
if token[0] == :attr or token[0] == :desc or token[0] == :task #No podemos recibir atributos, descripciones o tareas sin nada previo | |
return [:error, token] | |
else | |
return syntax_by_token tokens, token[0], num_token + 1 | |
end | |
elsif stat == :proj | |
if token[0] == :attr or token[0] == :desc #Si recibimos atributo o descripcion no cambiamos de estado | |
return syntax_by_token tokens, stat, num_token + 1 | |
else | |
return syntax_by_token tokens, token[0], num_token + 1 | |
end | |
elsif stat == :task | |
if token[0] == :attr or token[0] == :desc #Si recibimos atributo o descripcion no cambiamos de estado | |
return syntax_by_token tokens, stat, num_token + 1 | |
else | |
return syntax_by_token tokens, token[0], num_token + 1 | |
end | |
else | |
return [:error, token] | |
end | |
end | |
# ----- COMPILACION ----- | |
def self.compile_doc tokens | |
return compile_tokens tokens, :idle, 0, nil, nil | |
end | |
def self.compile_tokens tokens, stat, num_token, id_project, id_task | |
if tokens.size == num_token | |
return [:ok] | |
end | |
token = tokens[num_token] | |
if stat == :idle | |
if token[0] == :attr or token[0] == :desc or token[0] == :task #No podemos recibir atributos, descripciones o tareas sin nada previo | |
return [:error, token] | |
else | |
puts token | |
project = Project.create :name => token[1] | |
return compile_tokens tokens, token[0], num_token + 1, project.id, nil | |
end | |
elsif stat == :proj | |
if token[0] == :attr | |
Attribute.create :property => token[1][:attr], :value => token[1][:valor], :project_id => id_project | |
return compile_tokens tokens, stat, num_token + 1, id_project, id_task | |
elsif token[0] == :desc #Si recibimos atributo o descripcion no cambiamos de estado | |
Description.create :desc => token[1], :project_id => id_project | |
return compile_tokens tokens, stat, num_token + 1, id_project, id_task | |
elsif token[0] == :task | |
task = Task.create :name => token[1], :project_id => id_project | |
return compile_tokens tokens, :task, num_token + 1, id_project, task.id | |
elsif token[0] == :project | |
project = Project.create :name => token[1] | |
return compile_tokens tokens, :project, num_token + 1, project.id, nil | |
else | |
return [:error] | |
end | |
elsif stat == :task | |
if token[0] == :attr | |
Attribute.create :property => token[1][:attr], :value => token[1][:valor], :task_id => id_task | |
return compile_tokens tokens, stat, num_token + 1, id_project, id_task | |
elsif token[0] == :desc #Si recibimos atributo o descripcion no cambiamos de estado | |
Description.create :desc => token[1], :task_id => id_task | |
return compile_tokens tokens, stat, num_token + 1, id_project, id_task | |
elsif token[0] == :task | |
task = Task.create :name => token[1], :project_id => id_project | |
return compile_tokens tokens, :task, num_token + 1, id_project, task.id | |
elsif token[0] == :project | |
project = Project.create :name => token[1] | |
return compile_tokens tokens, :project, num_token + 1, project.id, nil | |
else | |
return [:error] | |
end | |
else | |
return [:error, token] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment