Compare commits
No commits in common. "parseur" and "main" have entirely different histories.
5 changed files with 0 additions and 320 deletions
|
@ -3,7 +3,6 @@ mod parser;
|
|||
mod job;
|
||||
mod variables;
|
||||
mod error;
|
||||
mod objects;
|
||||
|
||||
use std::process::exit;
|
||||
use variables::Variables;
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
use crate::objects::structure::Structure;
|
||||
|
||||
// Définition de l'objet Entree, utilise un object Structure.
|
||||
|
||||
pub struct Entree {
|
||||
/*
|
||||
* Correspond à une entrée. C'est ce que renvois le parser.
|
||||
*/
|
||||
size: i32,
|
||||
inputs: Vec<Structure>,
|
||||
}
|
||||
|
||||
impl Entree {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
size: 0,
|
||||
inputs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_structure(&mut self, structure: Structure) -> i8 {
|
||||
self.inputs.push(structure);
|
||||
self.size +=1;
|
||||
0
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
// definition des modules structures et entree pour qu'ils soient accessible aiyeurs dans le code.
|
||||
|
||||
pub mod structure;
|
||||
pub mod entree;
|
|
@ -1,129 +0,0 @@
|
|||
|
||||
// Definition des structures utilisés par le parseur.
|
||||
// s'utilise par l'appel de la fonction static parse, qui prends en param une ligne de commande
|
||||
// (Vect<String>) et qui renvois une Entree.
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Structure {
|
||||
/*
|
||||
* Il y à 5 types de structs differentes.
|
||||
* - commande
|
||||
* - control
|
||||
* - def variable
|
||||
* - def function
|
||||
* - pipes
|
||||
* - commentaires
|
||||
*/
|
||||
|
||||
name: String,
|
||||
contents: Vec<String>,
|
||||
}
|
||||
|
||||
impl Structure {
|
||||
/*
|
||||
* name: "commande"
|
||||
* contents: ["nom commande", "parametter", "arg1", ...]
|
||||
*
|
||||
* parametter define if the command is in background or not. For now, parametter can only be
|
||||
* either "" or "&"
|
||||
*/
|
||||
pub fn new_commande(cont: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: String::from("commande"),
|
||||
contents: cont,
|
||||
}
|
||||
}
|
||||
/*
|
||||
* name: "control"
|
||||
* contents: ["if|elif|else|while|for", "condition", "liste String avec (faudra la reparser
|
||||
* quand on tomberas dessus pour obtenir son objet de classe Entree) "]
|
||||
*/
|
||||
fn new_control(cont: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: String::from("control"),
|
||||
contents: cont,
|
||||
}
|
||||
}
|
||||
/*
|
||||
* name: "variable"
|
||||
* contents: ["type [string|list]","parametter", "name", "value"]
|
||||
*
|
||||
* parametter says if the variable is to export or not. right now it's either "" or "export"
|
||||
*/
|
||||
fn new_variable(cont: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: String::from("variable"),
|
||||
contents: cont,
|
||||
}
|
||||
}
|
||||
/*
|
||||
* name: "function"
|
||||
* contents: ["name", "nb parametter", "param1", ..., "liste String interieur fonction(faudra
|
||||
* la repasser quand on tomberas dessus pour obtenir son objet de classe Entree)"]
|
||||
*/
|
||||
fn new_function(cont: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: String::from("variable"),
|
||||
contents: cont,
|
||||
}
|
||||
}
|
||||
/*
|
||||
* name: "pipe"
|
||||
* contents: ["String Commande1 (faudra la repasser dans le parser)", "String Commande2(tout
|
||||
* le reste du pipe faudra le repasser dans le parser)"]
|
||||
*/
|
||||
fn new_pipe(cont: Vec<String>) -> Self {
|
||||
Self {
|
||||
name: String::from("pipe"),
|
||||
contents: cont,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* name: "commentaire"
|
||||
* contents: [une quote]
|
||||
*
|
||||
* est utilisé pour dire que l'utilisateur à oublié de refermer sa quote finale.
|
||||
*
|
||||
*/
|
||||
pub fn new_commentaire(cont: String) -> Self {
|
||||
Self {
|
||||
name: String::from("commentaire"),
|
||||
contents: vec![cont],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
name: String::new(),
|
||||
contents: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
if self.name == "" {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> &String {
|
||||
&self.name
|
||||
}
|
||||
pub fn get_contents(&self) -> &Vec<String> {
|
||||
&self.contents
|
||||
}
|
||||
|
||||
pub fn add_to_contents(&mut self, word: String) -> Self {
|
||||
// si le mot n'est pas vide l'ajoutter aux contents.
|
||||
if word != "" {
|
||||
let _ = &self.contents.push(word.to_string());
|
||||
}
|
||||
self.clone()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
157
src/parser.rs
157
src/parser.rs
|
@ -1,12 +1,3 @@
|
|||
|
||||
// This is the parser. It can be called by two commands:
|
||||
// parse(command_line: &String) -> Vec<String>
|
||||
// parse2(command_line: &String) -> Entree
|
||||
|
||||
use crate::objects::entree::Entree;
|
||||
use crate::objects::structure::Structure;
|
||||
|
||||
|
||||
fn parse_after_whitespace(char_splitted_command_line: &mut Vec<char>, argv: &mut Vec<String>) -> Vec<String> {
|
||||
let current_char_option = char_splitted_command_line.pop();
|
||||
|
||||
|
@ -42,8 +33,6 @@ fn parse_initial_state(char_splitted_command_line: &mut Vec<char>, current_arg:
|
|||
}
|
||||
|
||||
fn split_string_in_chars(string_to_split: &String) -> Vec<char> {
|
||||
// découpe une chaine de caractère &String en Vec<char et inverse le pour que
|
||||
// string_to_split.pop ressorte le premier caractère.
|
||||
string_to_split.chars().rev().collect()
|
||||
}
|
||||
|
||||
|
@ -56,149 +45,3 @@ pub fn parse(command_line: &String) -> Vec<String> {
|
|||
|
||||
argv
|
||||
}
|
||||
|
||||
// Up to this line is the old version parser.
|
||||
|
||||
|
||||
fn parser_word(word: String) -> Structure {
|
||||
// Génère à partir d'un mot une structure. Example, si le mot c jaaj=truc, alors cela créerras
|
||||
// une structure 'variable' si le mot c if|while|for|etc alors cela fait une structure 'control'
|
||||
// si cela est un mot finissant par () alors cela crée une structure 'fonction' sinon cela crée
|
||||
// une structure 'commande'
|
||||
|
||||
// TODo
|
||||
// Pour cette deuxieme version du parser, je ne vais pas faire les autres cas.
|
||||
|
||||
|
||||
if word == "" {
|
||||
// Dans le cas ou la fonction est appellé alors qu'il n'y as pas de mots
|
||||
Structure::empty()
|
||||
} else {
|
||||
// Dans le cas ou aucunes autres structures ne peuvent être crées, créer une structure
|
||||
// commande avec le mot dedans.
|
||||
Structure::new_commande(vec![word])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn generer_comments_a_partir_stack_quote(mut entree: Entree, mut stack_last_quote: Vec<char>) -> Entree {
|
||||
// Tant qu'il reste des quotes dans la stack, générer une Structure commentaire
|
||||
let mut last_quote = stack_last_quote.pop();
|
||||
|
||||
if last_quote.is_none() {
|
||||
// Si il n'y as plus de quote, renvoyer entree
|
||||
entree
|
||||
} else {
|
||||
// Sinon, rajoutter un commentaire à l'entree donnant la quote en question.
|
||||
entree.add_structure(Structure::new_commentaire(last_quote.expect("last_quote_is_none").to_string()));
|
||||
generer_comments_a_partir_stack_quote(entree, stack_last_quote)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_cas_fin_de_chaine(mut entree: Entree, stack_last_quote: Vec<char>, last_word: String, mut struct_in_construct: Structure) -> Entree {
|
||||
// Cas final, dans le cas ou le parser recoit un caractère vide.
|
||||
|
||||
if struct_in_construct.is_empty() {
|
||||
// Puisque la structure est vide, essayer de mettre le last_word dans une structure.
|
||||
struct_in_construct = parser_word(last_word);
|
||||
|
||||
if !struct_in_construct.is_empty() {
|
||||
// si une nouvelle structure est apparue, l'ajoutter à l'entrée.
|
||||
entree.add_structure(struct_in_construct);
|
||||
}
|
||||
} else {
|
||||
// Dans le cas ou la structure n'est pas vide, ajoutter le mot, et ajoutter la structure.
|
||||
entree.add_structure(struct_in_construct.add_to_contents(last_word));
|
||||
}
|
||||
// Finalement, regarder la stack des ' et ". Pour chaques commentaires ressortis, rajoutter une
|
||||
// structure commentaire le contenant.
|
||||
|
||||
generer_comments_a_partir_stack_quote(entree, stack_last_quote)
|
||||
|
||||
}
|
||||
|
||||
fn parse_recursif(mut entree: Entree, mut restant_a_parser: Vec<char>, mut stack_last_quote: Vec<char>, mut last_word: String, mut struct_in_construct: Structure) -> Entree {
|
||||
// Est le parseur initial, commence sa recursivitée avec une entree vide, une ligne de commande
|
||||
// en char, une pile vide, un mot vide, et une structure vide.
|
||||
//
|
||||
// Lis les caractères un par un, et détermine l'action à prendre avec chaques caractères.
|
||||
|
||||
// Etape 0; Lis le premier caractère de ce qu'il reste à parser.
|
||||
let current_char_option = restant_a_parser.pop();
|
||||
|
||||
// Etape 1, test cas ou la chaine est vide 'Cas final'
|
||||
if current_char_option.is_none() {
|
||||
parse_cas_fin_de_chaine(entree, stack_last_quote, last_word, struct_in_construct)
|
||||
|
||||
} else {
|
||||
let current_char = current_char_option.expect("current_char_is_None");
|
||||
// Etape 2, regarde si il y as des quotes dans la stack des quotes si oui regarder quel est
|
||||
// cette quote, et executer en fonction de cela la bonne fonction.
|
||||
if stack_last_quote[stack_last_quote.len()-1] == '\'' {
|
||||
// cas ou le quote est ' peu importe le caractère lus autre que ' le mettre dans
|
||||
// last_word et rappeler parse_recursif.
|
||||
if current_char == '\'' {
|
||||
let _ = stack_last_quote.pop();
|
||||
parse_recursif(entree, restant_a_parser, stack_last_quote, last_word, struct_in_construct)
|
||||
} else {
|
||||
last_word.push(current_char);
|
||||
parse_recursif(entree, restant_a_parser, stack_last_quote, last_word, struct_in_construct)
|
||||
}
|
||||
} else if stack_last_quote[stack_last_quote.len()-1] == '"' {
|
||||
// cas ou quote est " parser caractère sauf si "
|
||||
// ce cas existe pour au moment ou on rajoutteras la compatibilitée des variables.
|
||||
if current_char == '"' {
|
||||
let _ = stack_last_quote.pop();
|
||||
parse_recursif(entree, restant_a_parser, stack_last_quote, last_word, struct_in_construct)
|
||||
} else {
|
||||
last_word.push(current_char);
|
||||
parse_recursif(entree, restant_a_parser, stack_last_quote, last_word, struct_in_construct)
|
||||
}
|
||||
} else {
|
||||
// maintenant que la stack des quote est vide, regardons si le dernier caractère entré
|
||||
// est une quote.
|
||||
if current_char == '"' || current_char == '\'' {
|
||||
// dans ce cas la, l'ajoutter à la stack
|
||||
stack_last_quote.push(current_char);
|
||||
parse_recursif(entree, restant_a_parser, stack_last_quote, last_word, struct_in_construct)
|
||||
} else if current_char == ';' {
|
||||
// regardons si c'est le ; caractère de fin de ligne.
|
||||
// TODO
|
||||
entree
|
||||
} else {
|
||||
// TODO
|
||||
entree
|
||||
}
|
||||
}
|
||||
//
|
||||
// Si oui, vérif ';'
|
||||
// Cas last_word et Structure vide, ignorer le caractère et rappeler le parser_recursif
|
||||
// Cas contraire, completer structure et l'ajoutter à entrer et rappeler le parser_recursif
|
||||
//
|
||||
// si '#' et last_word vide, renvoyer entree
|
||||
// si ' ' ajoutter last_word à structure, ou, cas ou structure vide, parser_word et
|
||||
// rappeler le parser_recursif
|
||||
//
|
||||
// pour tout les autres cas, ajouter char à last_word.
|
||||
|
||||
// TODO
|
||||
//entree // Ici faudra rappeler le parse_recursif pour passer au caractère suivant.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn parse2(command_line: &String) -> Entree {
|
||||
// prends en paramettre un ligne de commande, et retourne une Entree.
|
||||
let mut entree: Entree = Entree::new();
|
||||
|
||||
// Etape 0, découper la commande_line: &String en command_line: Vec<char>
|
||||
let mut char_splitted_command_line: Vec<char> = split_string_in_chars(&command_line);
|
||||
|
||||
// Etape 1, préparer les variables pour lancer le parser recursif
|
||||
let mut stack_char_empty: Vec<char> = Vec::new();
|
||||
let mut empty_word: String = String::new();
|
||||
|
||||
// Etape 2, lancer le parser recursif. Il retournera une Entree bien parsé comme il faut.
|
||||
parse_recursif( entree, char_splitted_command_line, stack_char_empty, empty_word, Structure::empty())
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue