Skip to content

Instantly share code, notes, and snippets.

@fero23
Created April 28, 2016 06:00
Show Gist options
  • Save fero23/f4712a350a4f6b984c54992ddb483a66 to your computer and use it in GitHub Desktop.
Save fero23/f4712a350a4f6b984c54992ddb483a66 to your computer and use it in GitHub Desktop.
A rust parser example that parses a list of processes into html tables
#[macro_use]
extern crate rspc;
extern crate chrono;
use rspc::parsers::{Parser, ParserOps, number, string, ws, letter, not_of, character};
use rspc::parsers::combinators::many1;
use rspc::context::StringSource;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::fmt;
use chrono::*;
#[derive(Debug, Clone)]
struct Activity(u32, String, Vec<String>, bool);
impl fmt::Display for Activity {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", self.1)
}
}
impl Activity {
fn to_row(&self, start_date: Date<UTC>) -> (String, Date<UTC>) {
let tasks = self.2
.iter()
.map(|task| format!("<li>{}</li>", task))
.collect::<Vec<_>>()
.concat();
let end_date = start_date + Duration::seconds(self.0 as i64 * 86400);
(format!("<tr><td>{}</td><td><ul>{}</ul></td><td>{}</td><td>{}</td></tr>",
self.1.clone(),
tasks,
start_date.format("%d-%m-%Y").to_string(),
end_date.format("%d-%m-%Y").to_string()),
end_date + Duration::seconds(86400))
}
}
#[derive(Debug, Clone)]
enum ActivityNode {
Paralels(Vec<Activity>),
Single(Activity),
}
#[derive(Debug, Clone)]
struct Process(String, Vec<ActivityNode>);
impl fmt::Display for Process {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "{}", self.0)
}
}
impl Process {
fn to_table(&self, start_date: Date<UTC>) -> (String, Date<UTC>) {
let mut table = format!(r#"<table>
<tr>
<td colspan="4">
<ul>
<li>Proceso: {}</li>
<li>Objetivo:</li>
</ul>
</td>
</tr>
<tr>
<th>Actividad</th>
<th>Tarea</th>
<th>Fecha de Inicio</th>
<th>Fecha de Fin</th>
</tr>"#,
self.0);
let last_date = self.1.iter().fold(start_date, |date, an| match *an {
ActivityNode::Single(ref a) => {
let (td, new_date) = a.to_row(date);
table.push_str(&td);
new_date
}
ActivityNode::Paralels(ref parallels) => {
parallels.iter().fold(date, |d, a| {
let (td, new_date) = a.to_row(date);
table.push_str(&td);
if new_date > d {
new_date
} else {
d
}
})
}
});
table.push_str("\n</table>");
(table, last_date)
}
}
def_rules! {
rule roman_numbers: String = string("iii").or(string("ii")).or(string("iv")).or(string("i"))
.or(string("viii")).or(string("vii")).or(string("vi")).or(string("v"));
rule task: String = ws.and_r(roman_numbers).and_r(character('.'))
.and_r(ws).and_r(many1(not_of(".")).collect()).and_l(character('.')).and_l(ws);
rule activity: Activity = ws.and_r(letter).and_r(character('.'))
.and_r(ws).and_r(many1(not_of(":")).collect()).and_l(character(':')).and_l(ws)
.and(number).and_l(character('d')).and(letter)
.and_l(ws).and(many1(task))
.map(|(((content, n), ch), tasks)| Activity(n, content, tasks, if ch == 'p' {true} else {false}));
rule activity_nodes: Vec<ActivityNode> = many1(activity).map(|activities| {
let parallels = ActivityNode::Paralels(activities.iter().filter(|a| a.3).map(|a| a.clone()).collect::<Vec<_>>());
let mut others = activities.iter().filter(|a| !a.3).map(|a| ActivityNode::Single(a.clone())).collect::<Vec<_>>();
others.push(parallels);
others
});
rule process: Process = ws.and_r(number).and_r(character('.'))
.and_r(ws).and_r(many1(not_of(".")).collect()).and_l(character('.')).and_l(ws)
.and(activity_nodes).map(|(content, activities)| Process(content, activities));
}
fn main() {
let mut file = File::open("procs.txt").unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
let processes = many1(process).parse(StringSource::new(&contents)).unwrap();
let start_date = UTC.ymd(2016, 4, 1);
let mut processes_str = String::new();
processes.iter().fold(start_date, |date, process| {
let (table, new_date) = process.to_table(date);
processes_str.push_str(&table);
new_date
});
let html = format!(r#"<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
table, th, td {{
border: 1px solid black;
border-collapse: collapse;
}}
table {{
margin: 5px;
}}
th, td {{
padding: 5px;
}}
</style>
</head>
<body>
{}
</body>
</html>"#,
processes_str);
let mut file = File::create("output.html").unwrap();
file.write(html.as_bytes()).unwrap();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
table {
margin: 5px;
}
th, td {
padding: 5px;
}
</style>
</head>
<body>
<table>
<tr>
<td colspan="4">
<ul>
<li>Proceso: Analizar requerimientos del cliente</li>
<li>Objetivo:</li>
</ul>
</td>
</tr>
<tr>
<th>Actividad</th>
<th>Tarea</th>
<th>Fecha de Inicio</th>
<th>Fecha de Fin</th>
</tr><tr><td> Analizar los procesos del negocio</td><td><ul><li> Definir los procesos del negocio a automatizar</li><li> Verificar el alcance del sistema anterior en los procesos actuales de la empresa</li><li> Enlistar las fallas y posibles mejoras de la implementación del sistema anterior</li><li> Delimitar el alcance del nuevo software</li></ul></td><td>01-04-2016</td><td>11-04-2016</td></tr><tr><td> Delimitar los requerimientos del cliente</td><td><ul><li> Obtener las necesidades de información de todas las áreas implicadas</li><li> Recopilar las entradas y salidas de los procesos del negocio a automatizar</li><li> Delimitar las políticas de la empresa que afectan los procesos de negocio y tecnologías a desarrollar</li><li> Establecer una lista de mejoras a las herramientas actuales</li></ul></td><td>12-04-2016</td><td>27-04-2016</td></tr><tr><td> Definir formalmente los requerimientos</td><td><ul><li> Definir de requerimientos funcionales</li><li> Definir de características del sistema (requerimientos no funcionales)</li><li> Diagramar casos de uso y escenarios basados en requerimientos funcionales</li><li> Establecer una matriz de riesgos de implementación</li></ul></td><td>28-04-2016</td><td>05-05-2016</td></tr><tr><td> Planificar la implementación</td><td><ul><li> Definir la estrategia de migración</li><li> Definir estrategias de mitigación para los riesgos</li><li> Delimitar cada una de las tareas y procesos de implementación</li><li> Establecer responsables para cada una de las tareas</li><li> Calendarizar la realización de cada tarea</li><li> Identificar de los recursos necesarios para llevar a cabo el proyecto</li><li> Elaborar el presupuesto del proyecto</li><li> Definir de un contrato de implementación</li></ul></td><td>06-05-2016</td><td>13-05-2016</td></tr>
</table><table>
<tr>
<td colspan="4">
<ul>
<li>Proceso: Elaborar vistas arquitecturales (diagramas)</li>
<li>Objetivo:</li>
</ul>
</td>
</tr>
<tr>
<th>Actividad</th>
<th>Tarea</th>
<th>Fecha de Inicio</th>
<th>Fecha de Fin</th>
</tr><tr><td> Definir la vista lógica</td><td><ul><li> Elaborar el diagrama de actividad para cada proceso</li><li> Definir los posibles estados entre actividades en un diagrama de estados</li><li> Describir los datos utilizados en cada proceso en un diccionario de datos</li><li> Agrupar los datos del diccionario de datos según las entidades que describen en un diagrama de datos</li></ul></td><td>14-05-2016</td><td>24-05-2016</td></tr><tr><td> Diseñar la vista de desarrollo</td><td><ul><li> Traducir el diagrama de datos al diagrama de clases de la aplicación</li><li> Agrupar las clases en componentes del sistema en el diagrama de componentes</li><li> Nombrar los espacios lógicos entre clases con el diagrama de paquetes</li></ul></td><td>25-05-2016</td><td>01-06-2016</td></tr><tr><td> Describir la vista de despliegue</td><td><ul><li> Asignarle un dispositivo físico (hardware) a cada componente del sistema</li><li> Describir la distribución hardware/software usando un diagrama de despliegue</li></ul></td><td>02-06-2016</td><td>09-06-2016</td></tr><tr><td> Construir un prototipo</td><td><ul><li> Elaborar un prototipo del software usando las vistas definidas</li><li> Demostrar al cliente la funcionalidad del prototipo</li><li> Obtener retroalimentación del cliente por la funcionalidad requerida</li></ul></td><td>10-06-2016</td><td>25-06-2016</td></tr>
</table><table>
<tr>
<td colspan="4">
<ul>
<li>Proceso: Implementar los componentes del sistema</li>
<li>Objetivo:</li>
</ul>
</td>
</tr>
<tr>
<th>Actividad</th>
<th>Tarea</th>
<th>Fecha de Inicio</th>
<th>Fecha de Fin</th>
</tr><tr><td> Implementar la base de datos</td><td><ul><li> Traducir del modelo lógico de datos al físico</li><li> Implementar del modelo lógico en el gestor de base de datos</li><li> Ejecutar el plan de migración de los datos del sistema anterior</li><li> Optimizar el gestor con índices y vistas</li><li> Establecer controles de acceso por usuario</li></ul></td><td>26-06-2016</td><td>16-07-2016</td></tr><tr><td> Desarrollar la capa de aplicación</td><td><ul><li> Implementar de la capa de modelo</li><li> Implementar las vistas de usuario</li><li> Implementar los controladores</li><li> Realizar pruebas unitarias y de integración</li></ul></td><td>26-06-2016</td><td>10-08-2016</td></tr><tr><td> Elaborar la especificación</td><td><ul><li> Documentar de componentes de software</li><li> Documentar configuración de despliegue</li><li> Elaborar especificación recopilando la documentación existente</li><li> Redactar un manual de usuario</li></ul></td><td>26-06-2016</td><td>25-08-2016</td></tr>
</table><table>
<tr>
<td colspan="4">
<ul>
<li>Proceso: Implantar y dar seguimiento al nuevo sistema</li>
<li>Objetivo:</li>
</ul>
</td>
</tr>
<tr>
<th>Actividad</th>
<th>Tarea</th>
<th>Fecha de Inicio</th>
<th>Fecha de Fin</th>
</tr><tr><td> Implantación del sistema</td><td><ul><li> Configurar el hardware y software según la distribución especificada</li><li> Cargar los componentes de software en cada dispositivo</li><li> Verificar que todos los dispositivos se integren y comuniquen correctamente</li><li> Validar si el sistema logra realizar todas las funciones especificadas</li></ul></td><td>26-08-2016</td><td>10-09-2016</td></tr><tr><td> Capacitación de usuarios</td><td><ul><li> Repartir manuales de usuario a todos los usuarios del sistema</li><li> Impartir conferencias en las que se muestren las funcionalidades básicas del sistema a todos los interesados</li><li> Dar seguimiento a cada usuario y obtener su retroalimentación para nuevas iteraciones</li></ul></td><td>26-08-2016</td><td>25-09-2016</td></tr><tr><td> Mantenimiento preventivo</td><td><ul><li> Realizar pruebas sobre la implantación in-situ</li><li> Buscar posibles escenarios de fallo</li><li> Verificar que todos los requerimientos del cliente se cumplan</li><li> Corregir los bugs que se hayan identificado</li><li> Optimizar componentes de software y distribución</li></ul></td><td>26-08-2016</td><td>25-09-2016</td></tr>
</table>
</body>
</html>
1. Analizar requerimientos del cliente.
a. Analizar los procesos del negocio: 10ds
i. Definir los procesos del negocio a automatizar.
ii. Verificar el alcance del sistema anterior en los procesos actuales de la empresa.
iii. Enlistar las fallas y posibles mejoras de la implementación del sistema anterior.
iv. Delimitar el alcance del nuevo software.
b. Delimitar los requerimientos del cliente: 15ds
i. Obtener las necesidades de información de todas las áreas implicadas.
ii. Recopilar las entradas y salidas de los procesos del negocio a automatizar.
iii. Delimitar las políticas de la empresa que afectan los procesos de negocio y tecnologías a desarrollar.
iv. Establecer una lista de mejoras a las herramientas actuales.
c. Definir formalmente los requerimientos: 7ds
i. Definir de requerimientos funcionales.
ii. Definir de características del sistema (requerimientos no funcionales).
iii. Diagramar casos de uso y escenarios basados en requerimientos funcionales.
iv. Establecer una matriz de riesgos de implementación.
d. Planificar la implementación: 7ds
i. Definir la estrategia de migración.
ii. Definir estrategias de mitigación para los riesgos.
iii. Delimitar cada una de las tareas y procesos de implementación.
iv. Establecer responsables para cada una de las tareas.
v. Calendarizar la realización de cada tarea.
vi. Identificar de los recursos necesarios para llevar a cabo el proyecto.
vii. Elaborar el presupuesto del proyecto.
viii. Definir de un contrato de implementación.
2. Elaborar vistas arquitecturales (diagramas).
a. Definir la vista lógica: 10ds
i. Elaborar el diagrama de actividad para cada proceso.
ii. Definir los posibles estados entre actividades en un diagrama de estados.
iii. Describir los datos utilizados en cada proceso en un diccionario de datos.
iv. Agrupar los datos del diccionario de datos según las entidades que describen en un diagrama de datos.
b. Diseñar la vista de desarrollo: 7ds
i. Traducir el diagrama de datos al diagrama de clases de la aplicación.
ii. Agrupar las clases en componentes del sistema en el diagrama de componentes.
iii. Nombrar los espacios lógicos entre clases con el diagrama de paquetes.
c. Describir la vista de despliegue: 7ds
i. Asignarle un dispositivo físico (hardware) a cada componente del sistema.
ii. Describir la distribución hardware/software usando un diagrama de despliegue.
d. Construir un prototipo: 15ds
i. Elaborar un prototipo del software usando las vistas definidas.
ii. Demostrar al cliente la funcionalidad del prototipo.
iii. Obtener retroalimentación del cliente por la funcionalidad requerida.
3. Implementar los componentes del sistema.
a. Implementar la base de datos: 20dp
i. Traducir del modelo lógico de datos al físico.
ii. Implementar del modelo lógico en el gestor de base de datos.
iii. Ejecutar el plan de migración de los datos del sistema anterior.
iv. Optimizar el gestor con índices y vistas.
v. Establecer controles de acceso por usuario.
b. Desarrollar la capa de aplicación: 45dp
i. Implementar de la capa de modelo.
ii. Implementar las vistas de usuario.
iii. Implementar los controladores.
iv. Realizar pruebas unitarias y de integración.
c. Elaborar la especificación: 60dp
i. Documentar de componentes de software.
ii. Documentar configuración de despliegue.
iii. Elaborar especificación recopilando la documentación existente.
iv. Redactar un manual de usuario.
4. Implantar y dar seguimiento al nuevo sistema.
a. Implantación del sistema: 15dp
i. Configurar el hardware y software según la distribución especificada.
ii. Cargar los componentes de software en cada dispositivo.
iii. Verificar que todos los dispositivos se integren y comuniquen correctamente.
iv. Validar si el sistema logra realizar todas las funciones especificadas.
b. Capacitación de usuarios: 30dp
i. Repartir manuales de usuario a todos los usuarios del sistema.
ii. Impartir conferencias en las que se muestren las funcionalidades básicas del sistema a todos los interesados.
iii. Dar seguimiento a cada usuario y obtener su retroalimentación para nuevas iteraciones.
c. Mantenimiento preventivo: 30dp
i. Realizar pruebas sobre la implantación in-situ.
ii. Buscar posibles escenarios de fallo.
iii. Verificar que todos los requerimientos del cliente se cumplan.
iv. Corregir los bugs que se hayan identificado.
v. Optimizar componentes de software y distribución.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment