lib_ruby_parser/lexer/
parse_qmark.rs1use crate::lex_states::*;
2use crate::lexer::*;
3use crate::maybe_byte::*;
4use crate::source::buffer::*;
5use crate::DiagnosticMessage;
6
7impl Lexer {
8 fn parse_qmark_ternary(&mut self, c: MaybeByte) -> Result<i32, ()> {
9 self.buffer.pushback(c);
10 self.lex_state.set(EXPR_VALUE);
11 Ok(Self::tEH)
12 }
13
14 pub(crate) fn parse_qmark(&mut self, space_seen: bool) -> Result<i32, ()> {
15 if self.lex_state.is_end() {
16 self.lex_state.set(EXPR_VALUE);
17 return Ok(Self::tEH);
18 }
19 let mut c = self.nextc();
20 if c.is_eof() {
21 self.compile_error(
22 DiagnosticMessage::IncompleteCharacterSyntax {},
23 self.current_loc(),
24 );
25 return Ok(Self::END_OF_INPUT);
26 }
27 if c.is_space() {
28 if !self.lex_state.is_arg() {
29 if let Some(c2) = c.escaped_control_code() {
30 self.warn_space_char(c2, "?");
31 }
32 }
33 return self.parse_qmark_ternary(c);
34 }
35 self.newtok();
36
37 if !self.is_ascii() {
38 if self.tokadd_mbchar(c).is_err() {
39 return Ok(Self::END_OF_INPUT);
40 }
41 } else if (c.is_alnum() || c == b'_')
42 && self.buffer.pcur < self.buffer.pend
43 && self.buffer.is_identchar(self.buffer.pcur, self.buffer.pend)
44 {
45 if space_seen {
46 let start = self.buffer.pcur - 1;
47 let mut ptr = start;
48 loop {
49 let n = self.multibyte_char_len(ptr);
50 match n {
51 Some(n) => ptr += n,
52 None => return Ok(Self::END_OF_INPUT),
53 }
54
55 if !(ptr < self.buffer.pend && self.buffer.is_identchar(ptr, self.buffer.pend))
56 {
57 break;
58 }
59 }
60 self.warn(
61 DiagnosticMessage::AmbiguousTernaryOperator {
62 condition: String::from_utf8_lossy(
63 self.buffer.substr_at(start, ptr).unwrap(),
64 )
65 .into_owned(),
66 },
67 self.loc(start - 1, start),
68 )
69 }
70 return self.parse_qmark_ternary(c);
71 } else if c == b'\\' {
72 if self.buffer.peek(b'u') {
73 self.nextc();
74 self.tokadd_utf8(None, 0, 0);
75 } else if !self.buffer.is_eol() && !self.char_at(self.buffer.pcur).is_ascii() {
76 c = self.char_at(self.buffer.pcur);
77 self.nextc();
78 if self.tokadd_mbchar(c).is_err() {
79 return Ok(Self::END_OF_INPUT);
80 }
81 } else {
82 let byte = self.read_escape(0);
83 self.tokadd(byte);
84 }
85 } else {
86 self.tokadd(c);
87 }
88 self.tokfix();
89 let yylval = self.tokenbuf.take();
90 self.set_yylval_str(&yylval);
91 self.lex_state.set(EXPR_END);
92 Ok(Self::tCHAR)
93 }
94}