Skip to content

Instantly share code, notes, and snippets.

@pabloDon
Created March 18, 2013 18:18
Show Gist options
  • Save pabloDon/5189460 to your computer and use it in GitHub Desktop.
Save pabloDon/5189460 to your computer and use it in GitHub Desktop.
Compilador de textos para proyecto ToR
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