Skip to content

Commit 3d69f32

Browse files
author
Zibi Braniecki
committed
Initial attempt to write a zero-copy parser
Add a simple binary for testing Support menubar.ftl except of expressions Support multiline patterns Add EOF tests support Support basic JSON fixtures Support first set of comparison tests Support most of the comments Use serializer instead of deserializer Uncomment some fixture tests with slight modifications Support Junk Use ps.take_if in more places Support all reference fixtures Fix benches Support TermReference Support variants and select expression Update to rust 2018 preview 2 Use 2018 use extern macros Clean up whitespace collecting Remove try Update bench to Rust 2018 Support parsing of 0.7 reference tests Support CallExpressions
1 parent efc8813 commit 3d69f32

File tree

105 files changed

+6829
-2501
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+6829
-2501
lines changed

fluent-syntax/Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ description = """
44
Parser/Serializer tools for Fluent Syntax.
55
"""
66
version = "0.1.1"
7+
edition = "2018"
78
authors = [
89
"Zibi Braniecki <[email protected]>",
910
"Staś Małolepszy <[email protected]>"
@@ -16,7 +17,11 @@ keywords = ["localization", "l10n", "i18n", "intl", "internationalization"]
1617
categories = ["localization", "internationalization"]
1718

1819
[dependencies]
20+
clap = "2.32"
1921
annotate-snippets = {version = "0.1", features = ["color"]}
2022

2123
[dev-dependencies]
24+
serde = "1.0"
25+
serde_derive = "1.0"
26+
serde_json = "1.0"
2227
glob = "0.2"

fluent-syntax/benches/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
extern crate fluent_syntax;
44
extern crate test;
55

6+
use self::test::Bencher;
67
use fluent_syntax::parser::parse;
78
use std::fs::File;
89
use std::io;
910
use std::io::Read;
10-
use test::Bencher;
1111

1212
fn read_file(path: &str) -> Result<String, io::Error> {
13-
let mut f = try!(File::open(path));
13+
let mut f = File::open(path)?;
1414
let mut s = String::new();
15-
try!(f.read_to_string(&mut s));
15+
f.read_to_string(&mut s)?;
1616
Ok(s)
1717
}
1818

fluent-syntax/src/ast.rs

+87-80
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,136 @@
11
#[derive(Debug, PartialEq)]
2-
pub struct Resource {
3-
pub body: Vec<Entry>,
2+
pub struct Resource<'ast> {
3+
pub body: Vec<ResourceEntry<'ast>>,
44
}
55

66
#[derive(Debug, PartialEq)]
7-
pub enum Entry {
8-
Message(Message),
9-
Term(Term),
10-
Comment(Comment),
11-
Junk { content: String },
7+
pub enum ResourceEntry<'ast> {
8+
Entry(Entry<'ast>),
9+
Junk(&'ast str),
1210
}
1311

1412
#[derive(Debug, PartialEq)]
15-
pub struct Message {
16-
pub id: Identifier,
17-
pub value: Option<Pattern>,
18-
pub attributes: Option<Vec<Attribute>>,
19-
pub comment: Option<Comment>,
13+
pub enum Entry<'ast> {
14+
Message(Message<'ast>),
15+
Term(Term<'ast>),
16+
Comment(Comment<'ast>),
2017
}
2118

2219
#[derive(Debug, PartialEq)]
23-
pub struct Term {
24-
pub id: Identifier,
25-
pub value: Pattern,
26-
pub attributes: Option<Vec<Attribute>>,
27-
pub comment: Option<Comment>,
20+
pub struct Message<'ast> {
21+
pub id: Identifier<'ast>,
22+
pub value: Option<Pattern<'ast>>,
23+
pub attributes: Vec<Attribute<'ast>>,
24+
pub comment: Option<Comment<'ast>>,
2825
}
2926

3027
#[derive(Debug, PartialEq)]
31-
pub struct Pattern {
32-
pub elements: Vec<PatternElement>,
28+
pub struct Term<'ast> {
29+
pub id: Identifier<'ast>,
30+
pub value: Value<'ast>,
31+
pub attributes: Vec<Attribute<'ast>>,
32+
pub comment: Option<Comment<'ast>>,
3333
}
3434

3535
#[derive(Debug, PartialEq)]
36-
pub enum PatternElement {
37-
TextElement(String),
38-
Placeable(Expression),
36+
pub enum Value<'ast> {
37+
Pattern(Pattern<'ast>),
38+
VariantList { variants: Vec<Variant<'ast>> },
3939
}
4040

4141
#[derive(Debug, PartialEq)]
42-
pub enum Expression {
43-
StringExpression {
44-
value: String,
45-
},
46-
NumberExpression {
47-
value: Number,
48-
},
49-
MessageReference {
50-
id: Identifier,
51-
},
52-
ExternalArgument {
53-
id: Identifier,
54-
},
55-
SelectExpression {
56-
expression: Option<Box<Expression>>,
57-
variants: Vec<Variant>,
58-
},
59-
AttributeExpression {
60-
id: Identifier,
61-
name: Identifier,
62-
},
63-
VariantExpression {
64-
id: Identifier,
65-
key: VarKey,
66-
},
67-
CallExpression {
68-
callee: Function,
69-
args: Vec<Argument>,
70-
},
42+
pub struct Pattern<'ast> {
43+
pub elements: Vec<PatternElement<'ast>>,
7144
}
7245

7346
#[derive(Debug, PartialEq)]
74-
pub struct Attribute {
75-
pub id: Identifier,
76-
pub value: Pattern,
47+
pub enum PatternElement<'ast> {
48+
TextElement(&'ast str),
49+
Placeable(Expression<'ast>),
7750
}
7851

7952
#[derive(Debug, PartialEq)]
80-
pub struct Variant {
81-
pub key: VarKey,
82-
pub value: Pattern,
83-
pub default: bool,
53+
pub struct Attribute<'ast> {
54+
pub id: Identifier<'ast>,
55+
pub value: Pattern<'ast>,
8456
}
8557

8658
#[derive(Debug, PartialEq)]
87-
pub enum VarKey {
88-
VariantName(VariantName),
89-
Number(Number),
59+
pub struct Identifier<'ast> {
60+
pub name: &'ast str,
9061
}
9162

9263
#[derive(Debug, PartialEq)]
93-
pub enum Argument {
94-
Expression(Expression),
95-
NamedArgument { name: Identifier, val: ArgValue },
64+
pub struct Function<'ast> {
65+
pub name: &'ast str,
9666
}
9767

9868
#[derive(Debug, PartialEq)]
99-
pub enum ArgValue {
100-
Number(Number),
101-
String(String),
69+
pub struct Variant<'ast> {
70+
pub key: VariantKey<'ast>,
71+
pub value: Value<'ast>,
72+
pub default: bool,
10273
}
10374

104-
#[derive(Debug, PartialEq, Eq, Hash)]
105-
pub struct Identifier {
106-
pub name: String,
75+
#[derive(Debug, PartialEq)]
76+
pub enum VariantKey<'ast> {
77+
Identifier { name: &'ast str },
78+
NumberLiteral { value: &'ast str },
10779
}
10880

10981
#[derive(Debug, PartialEq)]
110-
pub struct Number {
111-
pub value: String,
82+
pub enum Comment<'ast> {
83+
Comment { content: Vec<&'ast str> },
84+
GroupComment { content: Vec<&'ast str> },
85+
ResourceComment { content: Vec<&'ast str> },
11286
}
11387

11488
#[derive(Debug, PartialEq)]
115-
pub struct VariantName {
116-
pub name: String,
89+
pub enum InlineExpression<'ast> {
90+
StringLiteral {
91+
value: &'ast str,
92+
},
93+
NumberLiteral {
94+
value: &'ast str,
95+
},
96+
VariableReference {
97+
id: Identifier<'ast>,
98+
},
99+
CallExpression {
100+
callee: Function<'ast>,
101+
positional: Vec<InlineExpression<'ast>>,
102+
named: Vec<NamedArgument<'ast>>,
103+
},
104+
AttributeExpression {
105+
reference: Box<InlineExpression<'ast>>,
106+
name: Identifier<'ast>,
107+
},
108+
VariantExpression {
109+
reference: Box<InlineExpression<'ast>>,
110+
key: VariantKey<'ast>,
111+
},
112+
MessageReference {
113+
id: Identifier<'ast>,
114+
},
115+
TermReference {
116+
id: Identifier<'ast>,
117+
},
118+
Placeable {
119+
expression: Box<Expression<'ast>>,
120+
},
117121
}
118122

119123
#[derive(Debug, PartialEq)]
120-
pub enum Comment {
121-
Comment { content: String },
122-
GroupComment { content: String },
123-
ResourceComment { content: String },
124+
pub struct NamedArgument<'ast> {
125+
pub name: Identifier<'ast>,
126+
pub value: InlineExpression<'ast>,
124127
}
125128

126129
#[derive(Debug, PartialEq)]
127-
pub struct Function {
128-
pub name: String,
130+
pub enum Expression<'ast> {
131+
InlineExpression(InlineExpression<'ast>),
132+
SelectExpression {
133+
selector: InlineExpression<'ast>,
134+
variants: Vec<Variant<'ast>>,
135+
},
129136
}

fluent-syntax/src/bin/parser.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
extern crate clap;
2+
extern crate fluent_syntax;
3+
4+
use std::fs::File;
5+
use std::io;
6+
use std::io::Read;
7+
8+
use clap::App;
9+
10+
use fluent_syntax::ast::Resource;
11+
use fluent_syntax::parser::parse;
12+
13+
fn read_file(path: &str) -> Result<String, io::Error> {
14+
let mut f = File::open(path)?;
15+
let mut s = String::new();
16+
f.read_to_string(&mut s)?;
17+
Ok(s)
18+
}
19+
20+
fn print_entries_resource(res: &Resource) {
21+
println!("{:#?}", res);
22+
}
23+
24+
fn main() {
25+
let matches = App::new("Fluent Parser")
26+
.version("1.0")
27+
.about("Parses FTL file into an AST")
28+
.args_from_usage(
29+
"-s, --silence 'disable output'
30+
<INPUT> 'Sets the input file to use'",
31+
)
32+
.get_matches();
33+
34+
let input = matches.value_of("INPUT").unwrap();
35+
36+
let source = read_file(&input).expect("Read file failed");
37+
38+
let res = parse(&source);
39+
40+
if matches.is_present("silence") {
41+
return;
42+
};
43+
44+
match res {
45+
Ok(res) => print_entries_resource(&res),
46+
Err((res, errors)) => {
47+
print_entries_resource(&res);
48+
println!("==============================\n");
49+
if errors.len() == 1 {
50+
println!("Parser encountered one error:");
51+
} else {
52+
println!("Parser encountered {} errors:", errors.len());
53+
}
54+
println!("-----------------------------");
55+
println!("{:#?}", errors);
56+
}
57+
};
58+
}

fluent-syntax/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
#![feature(box_syntax, box_patterns)]
2+
13
pub mod ast;
24
pub mod parser;

fluent-syntax/src/parser/errors/display.rs

-41
This file was deleted.

0 commit comments

Comments
 (0)