Finished lexer stub

Still need to test...
This commit is contained in:
Zach Dziura 2015-05-27 14:21:03 -04:00
parent 2423cd7d19
commit 97a0d856b2
3 changed files with 72 additions and 18 deletions

View file

@ -22,7 +22,7 @@ use std::fmt::{Display, Formatter, Result};
pub struct Error { pub struct Error {
kind: ErrorKind, kind: ErrorKind,
offender: String, offender: String,
desc: String, desc: String
} }
impl Error { impl Error {
@ -49,15 +49,17 @@ impl Display for Error {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum ErrorKind { pub enum ErrorKind {
InvalidOption, InvalidArgument,
MissingArgument, MissingArgument,
OptionFormat
} }
impl ErrorKind { impl ErrorKind {
fn description(&self) -> String { fn description(&self) -> String {
match *self { 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::MissingArgument => String::from("A required argument is missing:"),
ErrorKind::OptionFormat => String::from("An option was defined in the wrong format:")
} }
} }
} }

View file

@ -15,35 +15,87 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
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<Token, Error> {
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, short_name: String,
long_name: String, long_name: String,
is_arg: bool, is_arg: bool,
has_arg: bool, has_arg: bool,
is_group: bool,
description: String description: String
} }
impl Result { impl Token {
pub fn new(short_name: &str, long_name: &str, is_arg: bool, has_arg: bool, description: &str) pub fn new() -> Token {
-> Result { Token {
Result { short_name: String::new(),
short_name: String::from(short_name), long_name: String::new(),
long_name: String::from(long_name), is_arg: false,
is_arg: is_arg, has_arg: false,
has_arg: has_arg, is_group: false,
description: String::from(description) description: String::new()
} }
} }
} }
impl Display for Result { impl Display for Token {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> Result {
let repr = format!("-{}, --{} {}", self.short_name, self.long_name, self.description); let repr = format!("-{}, --{} {}", self.short_name, self.long_name, self.description);
write(self, "{}", repr) write(self, "{}", repr)
} }

View file

@ -62,7 +62,7 @@ pub fn parse(mut args: Args, options: &[&'static str]) -> Result<Matches, Error>
matches.insert(&arg, ""); matches.insert(&arg, "");
} }
} else { } else {
return Err(Error::new(ErrorKind::InvalidOption, arg)); return Err(Error::new(ErrorKind::InvalidArgument, arg));
} }
} else { // Probably a required arg } else { // Probably a required arg