Finished lexer stub
Still need to test...
This commit is contained in:
parent
2423cd7d19
commit
97a0d856b2
3 changed files with 72 additions and 18 deletions
|
@ -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:")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
80
src/lexer.rs
80
src/lexer.rs
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue