Skip to content

Commit 20491fc

Browse files
committed
update README, fix for getter on optional rule
1 parent a44046d commit 20491fc

14 files changed

+1229
-1154
lines changed

README.md

+24-17
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,39 @@ and [tests/my_tests.rs](tests/my_test.rs) for actual usage examples
88

99
### Implementation status
1010

11-
Everything is implemented, business logic is quite stable and well tested, but user facing
11+
Everything is implemented, "business" logic is quite stable and well tested, but user facing
1212
API is not very robust yet an very likely will have some changes.
1313

14+
For now development is going on in this repository
15+
but eventually it will be merged to main ANTLR4 repo
16+
1417
Currently requires nightly version of rust.
1518
This very likely will be the case until `specialization`,`try_blocks` and `unsize` features are stabilized.
1619

17-
Remaining core things:
18-
- [ ] Documentation
19-
- [ ] Quite some things are already documented but still far from perfect
20-
- [ ] API stabilization
21-
- [ ] Rust api guidelines compliance
22-
- [ ] more tests for API because it is quite different from Java
23-
- [ ] Code quality
24-
- [ ] Rustfmt fails to run currently
25-
- [ ] Clippy sanitation
26-
- [ ] Not all warning are fixed
27-
28-
See tracking [issue](https://github.com/antlr/antlr4/issues/1839) for more info
29-
30-
### Additional improvements:
20+
Remaining things before merge:
21+
- API stabilization
22+
- [ ] Rust api guidelines compliance
23+
- [ ] more tests for API because it is quite different from Java
3124
- make parsing zero copy(i.e. use &str(or Cow) instead String in token and &Token in tree nodes)
25+
- more generic `PredictionContext`
26+
- generic over ownership for string
3227
- profiling and performance optimizations
33-
- use & instead of Rc for nodes in parser
28+
- generate enum for labeled alternatives without redundant `Error` option
29+
- ? option to generate fields instead of getters by default
30+
31+
Can be done after merge:
32+
- Documentation
33+
- [ ] Quite some things are already documented but still far from perfect
34+
- Code quality
35+
- [ ] Rustfmt fails to run currently
36+
- [ ] Clippy sanitation
37+
- [ ] Not all warning are fixed
3438
- visitor
35-
- build.rs integration example
39+
- build.rs integration + example
3640
- run rustfmt on generated parser
41+
###### Long term improvements
42+
- use & instead of Rc for nodes in parser
43+
(requires GAT, otherwise it would be a problem for users that want ownership for parse tree)
3744
- support stable rust
3845
- support no_std(although alloc would still be required)
3946

grammars/Perf.g4

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
grammar Perf;
2+
3+
stat : expr ';'
4+
| expr '.'
5+
;
6+
7+
expr
8+
: ID
9+
| 'not' expr
10+
| expr 'and' expr
11+
| expr 'or' expr
12+
| '(' ID ')' expr
13+
| expr '?' expr ':' expr
14+
| 'between' expr 'and' expr
15+
;
16+
17+
ID: [a-zA-Z_][a-zA-Z_0-9]*;
18+
WS: [ \t\n\r\f]+ -> skip;

src/atn_state.rs

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub enum ATNBlockStart {
6363

6464
pub type ATNStateRef = usize;
6565

66+
67+
// todo no need for trait here, it is too slow for hot code
6668
pub trait ATNState: Sync + Send + Debug {
6769
fn has_epsilon_only_transitions(&self) -> bool;
6870

src/dfa_state.rs

-6
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ impl PartialEq for DFAState {
4545
}
4646
}
4747

48-
//impl Hash for *DFAState{
49-
// fn hash<H: Hasher>(&self, state: &mut H) {
50-
// unsafe{ (**self).hash(state) }
51-
// }
52-
//}
53-
5448
impl Hash for DFAState {
5549
fn hash<H: Hasher>(&self, state: &mut H) {
5650
self.configs.hash(state);

src/parser_rule_context.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ pub trait ParserRuleContext: RuleContext + CustomRuleContext + ParseTree + Any +
4141
fn enter_rule(&self, listener: &mut dyn Any);
4242
fn exit_rule(&self, listener: &mut dyn Any);
4343

44-
fn child_of_type<T: ParserRuleContext>(&self, pos: usize) -> Rc<T> where Self: Sized {
44+
fn child_of_type<T: ParserRuleContext>(&self, pos: usize) -> Option<Rc<T>> where Self: Sized {
4545
let result = self.get_children().iter()
4646
.filter(|&it| it.deref().type_id() == TypeId::of::<T>())
47-
.nth(pos).unwrap()
48-
.clone();
47+
.nth(pos)
48+
.cloned();
4949

50-
cast_rc(result)
50+
result.map(cast_rc)
5151
}
5252

5353
fn children_of_type<T: ParserRuleContext>(&self) -> Vec<Rc<T>> where Self: Sized {

src/transition.rs

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub enum TransitionType {
4747
TRANSITION_PRECEDENCE,
4848
}
4949

50+
// todo remove trait because it is too slow
5051
/// Transition between ATNStates
5152
pub trait Transition: Sync + Send + Debug + Any {
5253
fn get_target(&self) -> ATNStateRef;

tests/gen/csvlexer.rs

+53-53
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ pub const WS: isize = 4;
3232
pub const TEXT: isize = 5;
3333
pub const STRING: isize = 6;
3434
pub const channelNames: [&'static str; 0 + 2] = [
35-
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
35+
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
3636
];
3737

3838
pub const modeNames: [&'static str; 1] = [
39-
"DEFAULT_MODE"
39+
"DEFAULT_MODE"
4040
];
4141

4242
pub const ruleNames: [&'static str; 6] = [
43-
"T__0", "T__1", "T__2", "WS", "TEXT", "STRING"
43+
"T__0", "T__1", "T__2", "WS", "TEXT", "STRING"
4444
];
4545

4646

4747
pub const _LITERAL_NAMES: [Option<&'static str>; 4] = [
48-
None, Some("','"), Some("'\r'"), Some("'\n'")
48+
None, Some("','"), Some("'\r'"), Some("'\n'")
4949
];
5050
pub const _SYMBOLIC_NAMES: [Option<&'static str>; 7] = [
51-
None, None, None, None, Some("WS"), Some("TEXT"), Some("STRING")
51+
None, None, None, None, Some("WS"), Some("TEXT"), Some("STRING")
5252
];
5353
lazy_static! {
5454
static ref _shared_context_cache: Arc<PredictionContextCache> = Arc::new(PredictionContextCache::new());
@@ -57,22 +57,22 @@ lazy_static! {
5757

5858

5959
pub struct CSVLexer {
60-
base: BaseLexer<CSVLexerActions>,
60+
base: BaseLexer<CSVLexerActions>,
6161
// static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); }
6262
}
6363

6464
impl Deref for CSVLexer {
65-
type Target = BaseLexer<CSVLexerActions>;
65+
type Target = BaseLexer<CSVLexerActions>;
6666

67-
fn deref(&self) -> &Self::Target {
68-
&self.base
69-
}
67+
fn deref(&self) -> &Self::Target {
68+
&self.base
69+
}
7070
}
7171

7272
impl DerefMut for CSVLexer {
73-
fn deref_mut(&mut self) -> &mut Self::Target {
74-
&mut self.base
75-
}
73+
fn deref_mut(&mut self) -> &mut Self::Target {
74+
&mut self.base
75+
}
7676
}
7777

7878

@@ -90,29 +90,29 @@ impl CSVLexer {
9090

9191
fn add_error_listener(&mut self, _listener: Box<dyn ErrorListener>) {
9292
self.base.add_error_listener(_listener);
93-
}
93+
}
9494

95-
fn remove_error_listeners(&mut self) {
96-
self.base.remove_error_listeners()
97-
}
95+
fn remove_error_listeners(&mut self) {
96+
self.base.remove_error_listeners()
97+
}
9898

99-
fn get_grammar_file_name(&self) -> &'static str {
100-
"CSVLexer.g4"
101-
}
99+
fn get_grammar_file_name(&self) -> &'static str {
100+
"CSVLexer.g4"
101+
}
102102

103-
pub fn new(input: Box<dyn CharStream>) -> Self {
104-
antlr_rust::recognizer::check_version("0", "1");
105-
Self {
106-
base: BaseLexer::new_base_lexer(
107-
input,
108-
LexerATNSimulator::new_lexer_atnsimulator(
109-
_ATN.clone(),
110-
_decision_to_DFA.clone(),
111-
_shared_context_cache.clone(),
112-
),
113-
Box::new(CSVLexerActions {}),
114-
)
115-
}
103+
pub fn new(input: Box<dyn CharStream>) -> Self {
104+
antlr_rust::recognizer::check_version("0", "1");
105+
Self {
106+
base: BaseLexer::new_base_lexer(
107+
input,
108+
LexerATNSimulator::new_lexer_atnsimulator(
109+
_ATN.clone(),
110+
_decision_to_DFA.clone(),
111+
_shared_context_cache.clone(),
112+
),
113+
Box::new(CSVLexerActions {}),
114+
)
115+
}
116116
}
117117
}
118118

@@ -125,35 +125,35 @@ impl LexerRecog for CSVLexerActions {}
125125
impl Recognizer for CSVLexerActions {}
126126

127127
impl Actions for CSVLexerActions {
128-
type Recog = BaseLexer<CSVLexerActions>;
128+
type Recog = BaseLexer<CSVLexerActions>;
129129
}
130130

131131
impl CSVLexerActions {}
132132

133133
impl TokenSource for CSVLexer {
134-
fn next_token(&mut self) -> Box<dyn Token> {
135-
self.base.next_token()
136-
}
134+
fn next_token(&mut self) -> Box<dyn Token> {
135+
self.base.next_token()
136+
}
137137

138-
fn get_line(&self) -> isize {
139-
self.base.get_line()
140-
}
138+
fn get_line(&self) -> isize {
139+
self.base.get_line()
140+
}
141141

142-
fn get_char_position_in_line(&self) -> isize {
143-
self.base.get_char_position_in_line()
144-
}
142+
fn get_char_position_in_line(&self) -> isize {
143+
self.base.get_char_position_in_line()
144+
}
145145

146-
fn get_input_stream(&mut self) -> &mut dyn CharStream {
147-
self.base.get_input_stream()
148-
}
146+
fn get_input_stream(&mut self) -> &mut dyn CharStream {
147+
self.base.get_input_stream()
148+
}
149149

150-
fn get_source_name(&self) -> String {
151-
self.base.get_source_name()
152-
}
150+
fn get_source_name(&self) -> String {
151+
self.base.get_source_name()
152+
}
153153

154-
fn get_token_factory(&self) -> &dyn TokenFactory {
155-
self.base.get_token_factory()
156-
}
154+
fn get_token_factory(&self) -> &dyn TokenFactory {
155+
self.base.get_token_factory()
156+
}
157157
}
158158

159159

@@ -178,7 +178,7 @@ lazy_static! {
178178

179179

180180
const _serializedATN: &'static str =
181-
"\x03\u{608b}\u{a72a}\u{8133}\u{b9ed}\u{417c}\u{3be7}\u{7786}\u{5964}\x02\
181+
"\x03\u{608b}\u{a72a}\u{8133}\u{b9ed}\u{417c}\u{3be7}\u{7786}\u{5964}\x02\
182182
\x08\x2c\x08\x01\x04\x02\x09\x02\x04\x03\x09\x03\x04\x04\x09\x04\x04\x05\
183183
\x09\x05\x04\x06\x09\x06\x04\x07\x09\x07\x03\x02\x03\x02\x03\x03\x03\x03\
184184
\x03\x04\x03\x04\x03\x05\x06\x05\x17\x0a\x05\x0d\x05\x0e\x05\x18\x03\x05\

0 commit comments

Comments
 (0)