From 97a0d856b232b21d263ecf226d407334518f6846 Mon Sep 17 00:00:00 2001 From: Zach Dziura Date: Wed, 27 May 2015 14:21:03 -0400 Subject: [PATCH] Finished lexer stub Still need to test... --- src/errors.rs | 8 ++++-- src/lexer.rs | 80 ++++++++++++++++++++++++++++++++++++++++++--------- src/lib.rs | 2 +- 3 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index d5f2733..ab2ff02 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -22,7 +22,7 @@ use std::fmt::{Display, Formatter, Result}; pub struct Error { kind: ErrorKind, offender: String, - desc: String, + desc: String } impl Error { @@ -49,15 +49,17 @@ impl Display for Error { #[derive(Clone, Debug)] pub enum ErrorKind { - InvalidOption, + InvalidArgument, MissingArgument, + OptionFormat } impl ErrorKind { fn description(&self) -> String { match *self { - ErrorKind::InvalidOption => String::from("An invalid option was passed to the program:"), + ErrorKind::InvalidArgument => String::from("An invalid option was passed to the program:"), ErrorKind::MissingArgument => String::from("A required argument is missing:"), + ErrorKind::OptionFormat => String::from("An option was defined in the wrong format:") } } } diff --git a/src/lexer.rs b/src/lexer.rs index a25a5d9..0ba0e10 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -15,35 +15,87 @@ * along with this program. If not, see . */ -use std::fmt::{self, Display, Formatter}; +use std::fmt::{Display, Formatter, Result}; -pub fn analyze(input: &str) -> Result { +use errors::{Error, ErrorKind}; + +pub fn analyze(input: &str) -> Result { + let mut token = Token::new(); + token.is_arg = match &opt[..1] { + ":" => true, + _ => false + }; + + token.has_arg = match &opt[(opt.len() - 1)..] { + ":" => true, + _ => false + }; + + if token.is_arg && token.has_arg { + return Error::new(ErrorKind::OptionFormat, String::from(input)); + } + + let option = &input[1..(input.len() - 1)]; + + let mut current_stage = AnalysisStage::ShortName; + let mut current_char = option.chars().next(); + while current_char.is_some() { + match current_char { + '/' => { + current_stage = AnalysisStage::LongName; + continue; + }, + '(' => { + current_stage = AnalysisStage::Description; + continue; + }, + ')' => break, + _ => () + } + + match current_stage { + ShortName => token.short_name.push(current_char), + LongName => token.long_name.push(current_char), + Description => token.description.push(current_char) + } + + current_char = current_char.next(); + } + + Ok(token) } -pub struct Result { +enum AnalysisStage { + ShortName, + LongName, + Description +} + +pub struct Token { short_name: String, long_name: String, is_arg: bool, has_arg: bool, + is_group: bool, description: String } -impl Result { - pub fn new(short_name: &str, long_name: &str, is_arg: bool, has_arg: bool, description: &str) - -> Result { - Result { - short_name: String::from(short_name), - long_name: String::from(long_name), - is_arg: is_arg, - has_arg: has_arg, - description: String::from(description) +impl Token { + pub fn new() -> Token { + Token { + short_name: String::new(), + long_name: String::new(), + is_arg: false, + has_arg: false, + is_group: false, + description: String::new() } } } -impl Display for Result { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { +impl Display for Token { + fn fmt(&self, f: &mut Formatter) -> Result { let repr = format!("-{}, --{} {}", self.short_name, self.long_name, self.description); write(self, "{}", repr) } diff --git a/src/lib.rs b/src/lib.rs index 4c42714..9fd5271 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,7 @@ pub fn parse(mut args: Args, options: &[&'static str]) -> Result matches.insert(&arg, ""); } } else { - return Err(Error::new(ErrorKind::InvalidOption, arg)); + return Err(Error::new(ErrorKind::InvalidArgument, arg)); } } else { // Probably a required arg