wgsl_parse/
lib.rs

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
//! A parser for WGSL files, written directly from the [specification] with [lalrpop].
//!
//! # Parsing a source file
//!
//! ```rust
//! # use wgsl_parse::syntax::*;
//! let source = "@fragment fn frag_main() -> @location(0) vec4f { return vec4(1); }";
//! let parsed = wgsl_parse::Parser::parse_str(source).unwrap();
//!
//! let compare = TranslationUnit {
//!     global_directives: vec![],
//!     global_declarations: vec![GlobalDeclaration::Function(Function {
//!         attributes: vec![Attribute {
//!             name: "fragment".to_string(),
//!             arguments: None
//!         }],
//!         name: "frag_main".to_string(),
//!         parameters: vec![],
//!         return_attributes: vec![Attribute {
//!             name: "location".to_string(),
//!             arguments: Some(vec![Expression::Literal(LiteralExpression::AbstractInt(0))])
//!         }],
//!         return_type: Some(TypeExpression {
//!             name: "vec4f".to_string(),
//!             template_args: None
//!         }),
//!         body: CompoundStatement {
//!             attributes: vec![],
//!             statements: vec![Statement::Return(Some(Expression::FunctionCall(
//!                 FunctionCallExpression {
//!                     name: "vec4".to_string(),
//!                     template_args: None,
//!                     arguments: vec![Expression::Literal(LiteralExpression::AbstractInt(1))]
//!                 }
//!             )))]
//!         }
//!     })]
//! };
//!
//! assert_eq!(parsed, compare);
//! ```
//!
//! # Syntax tree
//!
//! See [syntax tree].
//!
//! Modifying the syntax tree:
//! ```rust
//!     let source = "const hello = 0u;";
//!     let mut module = wgsl_parse::Parser::parse_str(source).unwrap();
//!
//!     // modify the module as needed...
//!     let decl = &mut module
//!         .global_declarations
//!         .iter_mut()
//!         .find_map(|decl| match decl {
//!             wgsl_parse::syntax::GlobalDeclaration::Declaration(decl) => Some(decl),
//!             _ => None,
//!         })
//!         .unwrap();
//!     decl.name = "world".to_string();
//!
//!     assert_eq!(format!("{module}").trim(), "const world = 0u;");
//! ```
//!
//! # Stringification
//!
//! The syntax tree elements implement [`Display`][std::fmt::Display].
//! The display is always pretty-printed.
//!
//! TODO: implement :# for pretty vs. inline formatting.
//!
//! ```rust
//! let source = "@fragment fn frag_main() -> @location(0) vec4f { return vec4(1); }";
//! let mut module = wgsl_parse::Parser::parse_str(source).unwrap();
//!
//! // modify the module as needed...
//!
//! println!("{module}");
//! ```
//!
//! [lalrpop]: https://lalrpop.github.io/lalrpop/
//! [specification]: https://www.w3.org/TR/WGSL/
//! [syntax tree]: syntax
//! [spanned syntax tree]: syntax_spanned

pub mod error;
pub mod lexer;
pub mod parser;
pub mod span;
pub mod syntax;
pub mod syntax_spanned;

mod parser_support;
mod parser_support_spanned;
mod syntax_display;
mod syntax_display_spanned;
mod syntax_impl;

pub use lexer::Lexer;
pub use parser::Parser;

// pub fn parse_recognize(
//     source: &str,
// ) -> Result<(), ParseError<usize, Token, (usize, Error, usize)>> {
//     let lexer = Lexer::new(&source);
//     let parser = wgsl_recognize::TranslationUnitParser::new();
//     parser.parse(lexer)
// }

// pub fn parse_spanned(
//     source: &str,
// ) -> Result<TranslationUnit, ParseError<usize, Token, (usize, Error, usize)>> {
//     let lexer = Lexer::new(&source);
//     let parser = wgsl_spanned::TranslationUnitParser::new();
//     parser.parse(lexer)
// }