Skip to content

Commit 0fdd768

Browse files
committed
fix unneeded ambiguity, and then fix error handling
1 parent 8bcdfa5 commit 0fdd768

File tree

6 files changed

+142879
-144783
lines changed

6 files changed

+142879
-144783
lines changed

crates/quarto-markdown-pandoc/resources/error-corpus/_autogen-table.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
{
33
"column": 17,
44
"row": 0,
5-
"state": 1201,
5+
"state": 1133,
66
"sym": "end",
77
"errorInfo": {
88
"title": "Unclosed Span",
99
"message": "I reached the end of the block before finding a closing ']' for the span or link.",
1010
"captures": [
1111
{
1212
"column": 3,
13-
"lrState": 67,
13+
"lrState": 241,
1414
"row": 0,
1515
"size": 1,
1616
"sym": "[",
@@ -30,23 +30,23 @@
3030
{
3131
"column": 20,
3232
"row": 0,
33-
"state": 2520,
33+
"state": 2557,
3434
"sym": "class_specifier",
3535
"errorInfo": {
3636
"title": "Key-value Pair Before Class Specifier in Attribute",
3737
"message": "This class specifier appears after the key-value pair.",
3838
"captures": [
3939
{
4040
"column": 10,
41-
"lrState": 2632,
41+
"lrState": 2618,
4242
"row": 0,
4343
"size": 3,
4444
"sym": "key_value_key",
4545
"label": "key-value-begin"
4646
},
4747
{
4848
"column": 14,
49-
"lrState": 2473,
49+
"lrState": 2464,
5050
"row": 0,
5151
"size": 5,
5252
"sym": "key_value_value_token1",
@@ -67,15 +67,15 @@
6767
{
6868
"column": 18,
6969
"row": 0,
70-
"state": 1902,
70+
"state": 1926,
7171
"sym": "_error",
7272
"errorInfo": {
7373
"title": "Mismatched Delimiter in Attribute Specifier",
7474
"message": "I expected a '}', language specifier, an identifier, a class specifier, or a key-value pair.",
7575
"captures": [
7676
{
7777
"column": 17,
78-
"lrState": 1902,
78+
"lrState": 1926,
7979
"row": 0,
8080
"size": 1,
8181
"sym": "{",
@@ -95,23 +95,23 @@
9595
{
9696
"column": 3,
9797
"row": 0,
98-
"state": 772,
98+
"state": 932,
9999
"sym": "{",
100100
"errorInfo": {
101101
"title": "Missing Space After Div Fence",
102102
"message": "A space is required after ':::' when specifying div attributes.",
103103
"captures": [
104104
{
105105
"column": 0,
106-
"lrState": 772,
106+
"lrState": 932,
107107
"row": 0,
108108
"size": 3,
109109
"sym": "_fenced_div_start",
110110
"label": "fence-start"
111111
},
112112
{
113113
"column": 3,
114-
"lrState": 582,
114+
"lrState": 689,
115115
"row": 0,
116116
"size": 1,
117117
"sym": "{",

crates/quarto-markdown-pandoc/src/readers/qmd_error_messages.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -411,16 +411,18 @@ pub fn produce_error_message_json(
411411
}));
412412
}
413413

414-
// when erroring, produce the errors only for the
415-
// first failing state.
416-
return serde_json::to_string_pretty(&serde_json::json!({
417-
"tokens": tokens,
418-
"errorStates": error_states,
419-
}))
420-
.unwrap()
421-
.lines()
422-
.map(|s| s.to_string())
423-
.collect();
414+
if error_states.len() > 0 {
415+
// when erroring, produce the errors only for the
416+
// first failing state.
417+
return serde_json::to_string_pretty(&serde_json::json!({
418+
"tokens": tokens,
419+
"errorStates": error_states,
420+
}))
421+
.unwrap()
422+
.lines()
423+
.map(|s| s.to_string())
424+
.collect();
425+
}
424426
}
425427
}
426428
vec![]

crates/quarto-markdown-pandoc/src/utils/tree_sitter_log_observer.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,27 @@ pub struct TreeSitterParseLog {
4242
#[derive(Debug)]
4343
pub struct TreeSitterProcessLog {
4444
pub found_accept: bool,
45+
pub found_bad_message: bool,
4546
pub error_states: Vec<ProcessMessage>,
4647
pub current_message: Option<ProcessMessage>,
4748
}
4849

4950
impl TreeSitterProcessLog {
5051
pub fn is_good(&self) -> bool {
51-
self.found_accept && self.error_states.is_empty()
52+
self.found_accept && self.error_states.is_empty() && !self.found_bad_message
5253
}
5354
}
5455

5556
impl TreeSitterParseLog {
5657
pub fn is_good(&self) -> bool {
57-
// for every process, there needs to be at least one version that reached an accept state
58-
// with no error states
58+
// for every process, there can't be any version that reached a state
59+
// with error states
5960
for (_, process) in &self.processes {
60-
if process.is_good() {
61-
return true;
61+
if !process.is_good() {
62+
return false;
6263
}
6364
}
64-
false
65+
true
6566
}
6667
}
6768

@@ -165,6 +166,7 @@ impl TreeSitterLogObserver {
165166
let current_process = current_parse.processes.entry(version).or_insert_with(|| {
166167
TreeSitterProcessLog {
167168
found_accept: false,
169+
found_bad_message: false,
168170
error_states: vec![],
169171
current_message: None,
170172
}
@@ -179,7 +181,7 @@ impl TreeSitterLogObserver {
179181
});
180182
current_parse.current_process = Some(version);
181183
}
182-
"detect_error" | "skip_token" | "recover_to_previous" => {
184+
"detect_error" => {
183185
let current_parse = self
184186
.parses
185187
.last_mut()
@@ -245,6 +247,19 @@ impl TreeSitterLogObserver {
245247
sym: current_process_message.sym.clone(), // TODO would prefer not to clone here
246248
})
247249
}
250+
"skip_token" | "recover_to_previous" => {
251+
// we want to mark these processes as bad, but we don't want to record the state here
252+
// because we only care about states we find via "detect_error"
253+
let current_parse = self
254+
.parses
255+
.last_mut()
256+
.expect("No current parse to log process to");
257+
let current_process = current_parse
258+
.processes
259+
.get_mut(&current_parse.current_process.expect("No current process"))
260+
.expect("No current process message");
261+
current_process.found_bad_message = true;
262+
}
248263
"lex_external" | "lex_internal" | "reduce" => {}
249264
"accept" => {
250265
let current_parse = self

crates/tree-sitter-qmd/tree-sitter-markdown-inline/grammar.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ module.exports = grammar(add_inline_rules({
423423
"--",
424424
"---",
425425
"...",
426-
common.punctuation_without($, ['[', '{', '}', ']', "@", "_"]),
426+
common.punctuation_without($, ['[', '{', '}', ']', "@", "_", "*"]),
427427
$._whitespace,
428428
)),
429429
_code_span_text_base: $ => prec.right(choice(
@@ -461,12 +461,6 @@ function add_inline_rules(grammar) {
461461
alias($['_emphasis_underscore' + suffix_link], $.emphasis),
462462
alias($['_strong_emphasis_underscore' + suffix_link], $.strong_emphasis),
463463
];
464-
if (delimiter !== "star") {
465-
elements.push($._emphasis_open_star);
466-
}
467-
if (delimiter !== "underscore") {
468-
elements.push($._emphasis_open_underscore);
469-
}
470464
if (link) {
471465
elements = elements.concat([
472466
$.inline_link,

crates/tree-sitter-qmd/tree-sitter-markdown-inline/src/grammar.json

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,10 +3936,6 @@
39363936
"type": "STRING",
39373937
"value": ")"
39383938
},
3939-
{
3940-
"type": "STRING",
3941-
"value": "*"
3942-
},
39433939
{
39443940
"type": "STRING",
39453941
"value": "+"
@@ -4237,14 +4233,6 @@
42374233
"named": true,
42384234
"value": "strong_emphasis"
42394235
},
4240-
{
4241-
"type": "SYMBOL",
4242-
"name": "_emphasis_open_star"
4243-
},
4244-
{
4245-
"type": "SYMBOL",
4246-
"name": "_emphasis_open_underscore"
4247-
},
42484236
{
42494237
"type": "SYMBOL",
42504238
"name": "inline_link"
@@ -4301,10 +4289,6 @@
43014289
"named": true,
43024290
"value": "strong_emphasis"
43034291
},
4304-
{
4305-
"type": "SYMBOL",
4306-
"name": "_emphasis_open_underscore"
4307-
},
43084292
{
43094293
"type": "SYMBOL",
43104294
"name": "inline_link"
@@ -4361,10 +4345,6 @@
43614345
"named": true,
43624346
"value": "strong_emphasis"
43634347
},
4364-
{
4365-
"type": "SYMBOL",
4366-
"name": "_emphasis_open_star"
4367-
},
43684348
{
43694349
"type": "SYMBOL",
43704350
"name": "inline_link"
@@ -4421,14 +4401,6 @@
44214401
"named": true,
44224402
"value": "strong_emphasis"
44234403
},
4424-
{
4425-
"type": "SYMBOL",
4426-
"name": "_emphasis_open_star"
4427-
},
4428-
{
4429-
"type": "SYMBOL",
4430-
"name": "_emphasis_open_underscore"
4431-
},
44324404
{
44334405
"type": "SYMBOL",
44344406
"name": "inline_link"
@@ -4632,14 +4604,6 @@
46324604
},
46334605
"named": true,
46344606
"value": "strong_emphasis"
4635-
},
4636-
{
4637-
"type": "SYMBOL",
4638-
"name": "_emphasis_open_star"
4639-
},
4640-
{
4641-
"type": "SYMBOL",
4642-
"name": "_emphasis_open_underscore"
46434607
}
46444608
]
46454609
},
@@ -4692,10 +4656,6 @@
46924656
},
46934657
"named": true,
46944658
"value": "strong_emphasis"
4695-
},
4696-
{
4697-
"type": "SYMBOL",
4698-
"name": "_emphasis_open_underscore"
46994659
}
47004660
]
47014661
},
@@ -4748,10 +4708,6 @@
47484708
},
47494709
"named": true,
47504710
"value": "strong_emphasis"
4751-
},
4752-
{
4753-
"type": "SYMBOL",
4754-
"name": "_emphasis_open_star"
47554711
}
47564712
]
47574713
},
@@ -4804,14 +4760,6 @@
48044760
},
48054761
"named": true,
48064762
"value": "strong_emphasis"
4807-
},
4808-
{
4809-
"type": "SYMBOL",
4810-
"name": "_emphasis_open_star"
4811-
},
4812-
{
4813-
"type": "SYMBOL",
4814-
"name": "_emphasis_open_underscore"
48154763
}
48164764
]
48174765
},

0 commit comments

Comments
 (0)