10个版本
0.6.0 | 2023年4月18日 |
---|---|
0.5.1 | 2021年5月28日 |
0.4.1 | 2021年4月6日 |
0.3.4 | 2021年2月13日 |
0.2.0 | 2019年6月14日 |
#428 in 解析器实现
101 每月下载量
用于 4 个Crates(2个直接使用)
40KB
1K SLoC
ocl-include
简单的预处理器,实现了OpenCL源文件的#include机制。
关于
OpenCL API不提供将头文件包含到主文件中的机制,类似于C和C++。这个包是一个简单的预处理器,处理源文件中的#include ...
和#pragma once
指令,在文件系统或内存中收集它们,并将单个字符串输出,可以传递给OpenCL内核构建器。它还提供了一种机制,可以通过生成的字符串中的行号来查找源文件及其位置,这对于处理OpenCL编译器消息很有帮助。
文档
示例
假设您在./examples/
文件夹中有main.c
和header.h
文件
main.c
:
#include <header.h>
int main() {
return RET_CODE;
}
header.h
:
#pragma once
static const int RET_CODE = 0;
仅文件系统
以下代码从文件系统中获取main.c
并将其包含到header.h
中。
use ocl_include::*;
use std::path::Path;
fn main() {
let parser = Parser::builder()
.add_source(
source::Fs::builder()
.include_dir(&Path::new("./examples"))
.unwrap()
.build(),
)
.build();
let node = parser.parse(Path::new("main.c")).unwrap();
println!("{}", node.collect().0);
}
文件系统和内存
以下代码从内存中获取main.c
源代码,并从文件系统中将其包含到header.h
中。
use ocl_include::*;
use std::path::Path;
fn main() {
let main = r"
#include <header.h>
int main() {
return ~RET_CODE;
}
";
let parser = Parser::builder()
.add_source(
source::Mem::builder()
.add_file(&Path::new("main.c"), main.to_string())
.unwrap()
.build(),
)
.add_source(
source::Fs::builder()
.include_dir(&Path::new("./examples"))
.unwrap()
.build(),
)
.build();
let node = parser.parse(Path::new("main.c")).unwrap();
println!("{}", node.collect().0);
}
索引
Node.collect()
还返回一个Index
实例作为秒值。它可以用来通过生成的字符串中的行号查找源文件及其行号。
假设我们的OpenCL编译器接受生成的字符串并在某些行失败。但是行号对我们没有帮助,因为我们不知道这个行号来自哪个源文件。幸运的是,有一个Index::search
可以用来查找。
use ocl_include::*;
use std::path::Path;
fn main() {
let parser = Parser::builder()
.add_source(
source::Fs::builder()
.include_dir(&Path::new("./examples"))
.unwrap()
.build(),
)
.build();
let node = parser.parse(Path::new("main.c")).unwrap();
let (generated, index) = node.collect();
// Let's imagine that we complie the code here
// and got a compiler message at specific line
let line = 4;
println!(
"line {}: '{}'",
line,
generated.lines().nth(line - 1).unwrap()
);
// This will find the origin of this line
let (path, local_line) = index.search(line - 1).unwrap();
println!("origin: '{}' at line {}", path, local_line + 1);
}
其他预处理器功能
解析器还支持使用简单的预处理器门过滤代码(#if(n)def
,#else
,#endif
)。
默认情况下,过滤是禁用的,要为特定定义启用它,请使用 ParserBuilder::add_flag(flag_name, is_defined)
。
来源
来源是一个通过名称检索文件的处理器。
该仓库目前包含以下来源
Fs
:从文件系统中获取文件。Mem
:从内存中检索来源。
以下组合也是来源
Vec<S> where S: Source
:尝试从来源中依次检索文件。&S其中S:Source
Box<dyn Source>
Rc<S> 其中S:Source
许可
根据您的选择,许可为以下之一
- Apache License,版本2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的您有意提交以包含在作品中的任何贡献,将根据上述内容双许可,没有任何附加条款或条件。
依赖关系
~2.1-3MB
~53K SLoC