Skip to content

Commit

Permalink
Merge branch 'parse-literal' into 'master'
Browse files Browse the repository at this point in the history
Parse literal

See merge request ricos/truck/ruststep!7
  • Loading branch information
termoshtt committed Nov 11, 2020
2 parents e97b988 + e7f305e commit d3325d7
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 55 deletions.
18 changes: 6 additions & 12 deletions exp2rs/src/parser/entity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::identifier;
use super::simple_id;
use nom::{bytes::complete::*, character::complete::*, multi::*, sequence::*, IResult, Parser};

/// Parsed result of EXPRESS's ENTITY
Expand Down Expand Up @@ -48,11 +48,11 @@ pub struct Entity {
/// ```
pub fn explicit_attr(input: &str) -> IResult<&str, (Vec<String>, String)> {
tuple((
separated_list1(tuple((multispace0, tag(","), multispace0)), identifier),
separated_list1(tuple((multispace0, tag(","), multispace0)), simple_id),
multispace0,
tag(":"),
multispace0,
identifier, // FIXME this must be type instead of identifier
simple_id, // FIXME this must be type instead of simple_id
multispace0,
tag(";"),
))
Expand All @@ -61,15 +61,9 @@ pub fn explicit_attr(input: &str) -> IResult<&str, (Vec<String>, String)> {
}

fn entity_head(input: &str) -> IResult<&str, String> {
tuple((
tag("ENTITY"),
multispace1,
identifier,
multispace0,
tag(";"),
))
.map(|(_, _, id, _, _)| id)
.parse(input)
tuple((tag("ENTITY"), multispace1, simple_id, multispace0, tag(";")))
.map(|(_, _, id, _, _)| id)
.parse(input)
}

fn entity_end(input: &str) -> IResult<&str, ()> {
Expand Down
84 changes: 84 additions & 0 deletions exp2rs/src/parser/literal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use nom::{
branch::*, bytes::complete::*, character::complete::*, combinator::*, number::complete::double,
IResult, Parser,
};

#[derive(Debug, Clone, PartialEq)]
pub enum Logical {
False,
True,
Unknown,
}

#[derive(Debug, Clone, PartialEq)]
pub enum Literal {
Integer(u64),
Real(f64),
Logial(Logical),
}

/// 251 literal = binary_literal | logical_literal | real_literal | string_literal .
pub fn literal(input: &str) -> IResult<&str, Literal> {
alt((
logical_literal.map(|val| Literal::Logial(val)),
real_literal.map(|val| Literal::Real(val)),
// FIXME binary_literal,
// FIXME string_literal
))
.parse(input)
}

/// 255 logical_literal = `FALSE` | `TRUE` | `UNKNOWN` .
pub fn logical_literal(input: &str) -> IResult<&str, Logical> {
alt((
value(Logical::True, tag("TRUE")),
value(Logical::False, tag("FALSE")),
value(Logical::Unknown, tag("UNKNOWN")),
))
.parse(input)
}

/// 141 integer_literal = digits .
///
/// Negative integer, e.g. `-23`,
/// will be represented by the combination of `-` unary operator and integer literal `23`
///
/// Example
/// --------
///
/// ```
/// use exp2rs::parser;
/// use nom::Finish;
///
/// let (residual, value) = parser::integer_literal("123").finish().unwrap();
/// assert_eq!(value, 123);
/// assert_eq!(residual, "");
/// ```
pub fn integer_literal(input: &str) -> IResult<&str, u64> {
digit1.map(|d: &str| d.parse().unwrap()).parse(input)
}

/// 142 real_literal = integer_literal | ( digits `.` [ digits ] [ `e` [ sign ] digits ] ) .
///
/// Example
/// --------
///
/// ```
/// use exp2rs::parser;
/// use nom::Finish;
///
/// let (residual, value) = parser::real_literal("123").finish().unwrap();
/// assert_eq!(value, 123.0);
/// assert_eq!(residual, "");
///
/// let (residual, value) = parser::real_literal("123.456").finish().unwrap();
/// assert_eq!(value, 123.456);
/// assert_eq!(residual, "");
///
/// let (residual, value) = parser::real_literal("1.23e-5").finish().unwrap();
/// assert_eq!(value, 1.23e-5);
/// assert_eq!(residual, "");
/// ```
pub fn real_literal(input: &str) -> IResult<&str, f64> {
double.parse(input)
}
64 changes: 30 additions & 34 deletions exp2rs/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,50 @@
//! This module is based on [nom](https://github.com/Geal/nom) parser combinater.
mod entity;
mod literal;
mod schema;
mod simple_data_type;

pub use entity::*;
pub use literal::*;
pub use schema::*;
pub use simple_data_type::*;

use nom::{
branch::*, bytes::complete::*, character::complete::*, multi::*, sequence::*, IResult, Parser,
};

/// 7.4 Identifier
///
/// ```text
/// 143 simple_id = letter { letter | digit | ’_’ } .
/// 128 letter = ’a’ | ’b’ | ’c’ | ’d’ | ’e’ | ’f’ | ’g’ | ’h’ | ’i’ | ’j’ | ’k’ | ’l’ |’m’ | ’n’ | ’o’ | ’p’ | ’q’ | ’r’ | ’s’ | ’t’ | ’u’ | ’v’ | ’w’ | ’x’ |’y’ | ’z’ .
/// 124 digit = ’0’ | ’1’ | ’2’ | ’3’ | ’4’ | ’5’ | ’6’ | ’7’ | ’8’ | ’9’ .
///
/// Example
/// --------
///
/// ```
/// use exp2rs::parser;
/// use nom::Finish;
///
/// let (residual, id) = parser::simple_id("h").finish().unwrap();
/// assert_eq!(id, "h");
/// assert_eq!(residual, "");
///
/// let (residual, id) = parser::simple_id("homhom").finish().unwrap();
/// assert_eq!(id, "homhom");
/// assert_eq!(residual, "");
///
/// let (residual, id) = parser::simple_id("ho_mhom").finish().unwrap();
/// assert_eq!(id, "ho_mhom");
/// assert_eq!(residual, "");
///
/// let (residual, id) = parser::simple_id("h10o_1mh2om").finish().unwrap();
/// assert_eq!(id, "h10o_1mh2om");
/// assert_eq!(residual, "");
///
/// assert!(parser::simple_id("_homhom").finish().is_err());
/// assert!(parser::simple_id("1homhom").finish().is_err());
/// assert!(parser::simple_id("").finish().is_err());
/// ```
pub fn identifier(input: &str) -> IResult<&str, String> {
pub fn simple_id(input: &str) -> IResult<&str, String> {
tuple((alpha1, many0(alt((alphanumeric1, is_a("_"))))))
.map(|(head, tail)| format!("{}{}", head, tail.join("")))
.parse(input)
}

#[cfg(test)]
mod tests {
use nom::Finish;

#[test]
fn identifier() {
let (residual, id) = super::identifier("h").finish().unwrap();
assert_eq!(id, "h");
assert_eq!(residual, "");

let (residual, id) = super::identifier("homhom").finish().unwrap();
assert_eq!(id, "homhom");
assert_eq!(residual, "");

let (residual, id) = super::identifier("ho_mhom").finish().unwrap();
assert_eq!(id, "ho_mhom");
assert_eq!(residual, "");

let (residual, id) = super::identifier("h10o_1mh2om").finish().unwrap();
assert_eq!(id, "h10o_1mh2om");
assert_eq!(residual, "");

assert!(super::identifier("_homhom").finish().is_err());
assert!(super::identifier("1homhom").finish().is_err());
assert!(super::identifier("").finish().is_err());
}
}
12 changes: 3 additions & 9 deletions exp2rs/src/parser/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,9 @@ pub struct Schema {
}

fn schema_decl(input: &str) -> IResult<&str, String> {
tuple((
tag("SCHEMA"),
multispace1,
identifier,
multispace0,
tag(";"),
))
.map(|(_, _, id, _, _)| id)
.parse(input)
tuple((tag("SCHEMA"), multispace1, simple_id, multispace0, tag(";")))
.map(|(_, _, id, _, _)| id)
.parse(input)
}

fn schema_end(input: &str) -> IResult<&str, ()> {
Expand Down

0 comments on commit d3325d7

Please sign in to comment.