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
#![feature(rustc_private, plugin_registrar, quote, box_syntax)]
extern crate rustc;
extern crate rustc_plugin;
extern crate syntax;
extern crate partial;
use rustc_plugin::Registry;
use front::parser;
use front::ast::FGrammar;
mod ast;
mod visitor;
mod front;
mod middle;
mod back;
mod rust;
mod identifier;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_syntax_extension(
rust::Symbol::intern("grammar"),
rust::SyntaxExtension::IdentTT(Box::new(expand), None, true));
}
fn expand<'a, 'b>(cx: &'a mut rust::ExtCtxt<'b>, _sp: rust::Span, grammar_name: rust::Ident,
tts: Vec<rust::TokenTree>) -> Box<rust::MacResult + 'a>
{
parse(cx, grammar_name, tts)
}
fn abort_if_errors(cx: &rust::ExtCtxt) {
cx.parse_sess.span_diagnostic.abort_if_errors();
}
fn unwrap_parser_ast<'a>(cx: &rust::ExtCtxt, ast: rust::PResult<'a, FGrammar>) -> FGrammar {
match ast {
Ok(ast) => {
abort_if_errors(cx);
ast
}
Err(mut err_diagnostic) => {
err_diagnostic.emit();
abort_if_errors(cx);
panic!(rust::FatalError);
}
}
}
fn parse<'a, 'b>(cx: &'a mut rust::ExtCtxt<'b>, grammar_name: rust::Ident,
tts: Vec<rust::TokenTree>) -> Box<rust::MacResult + 'a>
{
let parser = parser::Parser::new(cx.parse_sess(), tts, grammar_name);
let ast = parser.parse_grammar();
let ast = unwrap_parser_ast(cx, ast);
let cx: &'a rust::ExtCtxt = cx;
middle::typecheck(cx, ast)
.and_next(|ast| back::compile(ast))
.unwrap_or_else(|| {
abort_if_errors(cx);
rust::DummyResult::any(rust::DUMMY_SP)
})
}