1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
//! # About //! //! `zypo-parser` is the primary parser implementation for the `zypo-rs` //! reference compiler. This package uses the [LALRPOP](https://github.com/lalrpop/lalrpop) //! library, a yacc-like `LR(1)` parser combiner for Rust. This crate also //! contains the AST (*abstract-syntax-tree*) for Zypo and all public AST structures, //! enums and associated functions are avalible at the base-level of this crate. //! //! *Please beware as this package is heavily work-in-progress and is developed //! alongside the main Zypo compiler as a sub-package. If you are looking for //! the base `zypo-rs` compiler, you may find it //! [here](https://gitlab.com/zypo/zypo-rs)*. //! //! # Examples //! //! Shortcut for parsing an AST or panicing if there is an error in any of the //! given input: //! //! ```rust //! use zypo_parser::{ //! Function, //! VarType, //! Parameter, //! ast_result //! }; // All but ast_result are from the AST. ast_result is the shortcut func //! //! fn main() { //! let input = "fun shortcut_test_func(my_param: int) {}"; //! let expected = vec![ //! Function { //! ident: "shortcut_test_func".to_string(), //! params: vec![ //! Parameter { ident: "my_param".to_string(), ty: VarType::Int } //! ], //! body: vec![], //! return_type: VarType::Void //! } //! ]; //! //! assert_eq!(ast_result(input), expected); //! } //! ``` //! //! More controllable but lower-level `LALRPOP` bind for manually handling the //! generated parsing errors: //! //! ```rust //! use zypo_parser::{ //! Function, //! VarType, //! parser //! }; // Function and VarType are from the AST, parser is generated by LALRPOP //! //! fn main() { //! let input = "fun test_func() {}"; //! let expected = vec![ //! Function { //! ident: "test_func".to_string(), //! params: vec![], //! body: vec![], //! return_type: VarType::Void //! } //! ]; //! //! assert_eq!(parser::GrammarParser::new().parse(input).unwrap(), expected); //! } //! ``` #[macro_use] extern crate lalrpop_util; mod ast; lalrpop_mod!(pub parser, "/grammar.rs"); pub use ast::*; /// Gets the abstract syntax tree generated from the parser of `zypo-rs`. This /// function will panic is parsing fails and is intended for developers aiming /// to implament the parser into code generation. /// /// Please see [Function] for more infomation of what this will immidiatly /// return. /// /// # Examples /// /// Basic function with 2 defined parameters: /// /// ```rust /// use zypo_parser::{ /// VarType, /// Function, /// Parameter, /// ast_result /// }; /// /// fn main() { /// let input = "fun test_function(my_int: int, some_string: str) {}"; /// let expected = vec![ /// Function { /// ident: "test_function".to_string(), /// params: vec![ /// Parameter { ident: "my_int".to_string(), ty: VarType::Int }, /// Parameter { ident: "some_string".to_string(), ty: VarType::Str } /// ], /// body: vec![], /// return_type: VarType::Void /// } /// ]; /// /// assert_eq!(ast_result(input), expected); /// } /// ``` pub fn ast_result(input: &str) -> Vec<Function> { parser::GrammarParser::new().parse(input).unwrap() } #[cfg(test)] mod tests { use super::*; /// Tests for the correct output of a basic function decleration with no /// defined body. #[test] fn basic_function_ast() { let input_str = "fun hello_there(hi: str) {}"; let expected = vec![Function { ident: "hello_there".to_string(), params: vec![Parameter { ident: "hi".to_string(), ty: VarType::Str, }], body: vec![], return_type: VarType::Void, }]; assert_eq!(ast_result(input_str), expected); } /// Tests a simple variable statement inside of the function #[test] fn while_loop_ast() { let input_str = "fun test_while() { var x: int = 54; }"; let expected = vec![Function { ident: "test_while".to_string(), params: vec![], body: vec![StatementNode::Variable(Variable { ident: "x".to_string(), ty: VarType::Int, body: Box::new(ExpressionNode::Constant(Constant::Int(54))), })], return_type: VarType::Void, }]; assert_eq!(ast_result(input_str), expected); } }