step_p21/parser/mod.rs
1//! Tokenize exchange structure string into [ast]
2//!
3//! ASCII encoding of exchange structure, a.k.a. STEP file, consists of
4//! following sections:
5//!
6//! - HEADER
7//! - ANCHOR (optional)
8//! - REFERENCE (optional)
9//! - DATA
10//! - SIGNATURE (optional)
11//!
12//! ANCHOR, REFERENCE, and SIGNATURE sections are optional.
13//! The syntax of STEP-file is common through schemas,
14//! i.e. the tokenize of STEP-file can be done without reading any EXPRESS
15//! schema. A target schema is specified in the HEADER section,
16//! and it determines how we should understand AST.
17//!
18//! Example
19//! --------
20//!
21//! ```
22//! use std::{fs, path::*};
23//!
24//! // Read ABC Dataset's STEP file format example
25//! let step_file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
26//! .join("tests/steps/00000050_80d90bfdd2e74e709956122a_step_000.step");
27//! let step_str = fs::read_to_string(step_file).unwrap();
28//!
29//! // Parse STEP file into `Exchange` struct
30//! let ex = step_p21::parser::parse(&step_str).unwrap();
31//! ```
32
33pub mod basic;
34pub mod combinator;
35pub mod exchange;
36pub mod token;
37
38use crate::{
39 ast,
40 error::{Result, TokenizeFailed},
41};
42use nom::Finish;
43
44/// Parse HEADER section
45///
46/// Example
47/// --------
48///
49/// ```
50/// let step_str = r#"
51/// HEADER;
52/// FILE_DESCRIPTION(('叛逆の物語', '魔法少女まどか☆マギカ'), '4;3');
53/// FILE_NAME(
54/// '/madoka/magica/rebellion.step',
55/// '2013-10-26T10:30:00+09:00',
56/// ('Mami Tomoe', 'Madoka Kaname', 'Sayaka Miki', 'Kyoko Sakura', 'Homura Akemi'),
57/// ('Puella Magi Holy Quintet'),
58/// 'homu',
59/// 'Magica Quartet',
60/// 'qb@incubator.com'
61/// );
62/// FILE_SCHEMA(('MAGICAL_GIRL'));
63/// ENDSEC;
64/// "#.trim();
65///
66/// let (residual, header) = step_p21::parser::parse_header(&step_str).unwrap();
67/// assert_eq!(residual, ""); // consume HEADER section of `step_str`
68/// ```
69pub fn parse_header(input: &str) -> Result<(&str, Vec<ast::Record>)> {
70 match exchange::header_section(input).finish() {
71 Ok((input, records)) => Ok((input, records)),
72 Err(e) => Err(TokenizeFailed::new(input, e).into()),
73 }
74}
75
76/// Parse entire STEP file
77pub fn parse(input: &str) -> Result<ast::Exchange> {
78 match exchange::exchange_file(input).finish() {
79 Ok((_residual, ex)) => Ok(ex),
80 Err(e) => Err(TokenizeFailed::new(input, e).into()),
81 }
82}