Skip to main content

eventql_parser/
token.rs

1//! Token types for lexical analysis.
2//!
3//! This module defines the types used during tokenization (lexical analysis)
4//! of EventQL queries. Tokens are the atomic units produced by the lexer
5//! and consumed by the parser.
6//!
7//! # Core Types
8//!
9//! - [`Token`] - A token with position information
10//! - [`Sym`] - The symbol/category of a token
11//! - [`Operator`] - Arithmetic, comparison, and logical operators
12//! - [`Symbol`] - Structural symbols (parentheses, brackets, etc.)
13
14use nom_locate::LocatedSpan;
15use serde::{Deserialize, Serialize};
16use std::fmt::{Display, Formatter};
17
18/// Symbol type representing the category and value of a token.
19///
20/// This enum encompasses all the different types of tokens that can appear
21/// in an EventQL query, from keywords and operators to literals and symbols.
22#[derive(Clone, Debug, Copy, Serialize)]
23pub enum Sym<'a> {
24    /// Identifier (variable names, keywords not yet classified)
25    Id(&'a str),
26    /// String literal
27    String(&'a str),
28    /// Numeric literal
29    Number(f64),
30    /// Keyword (FROM, WHERE, etc.)
31    Keyword(&'a str),
32    /// Operator (+, -, ==, AND, etc.)
33    Operator(Operator),
34    /// Structural symbol (parentheses, brackets, etc.)
35    Symbol(Symbol),
36    /// End of file marker
37    Eof,
38}
39
40impl Display for Sym<'_> {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        match self {
43            Sym::Id(id) => write!(f, "{}", id),
44            Sym::String(s) => write!(f, "\"{}\"", s),
45            Sym::Number(n) => write!(f, "{}", n),
46            Sym::Keyword(kw) => write!(f, "{}", kw.to_uppercase()),
47            Sym::Operator(op) => write!(f, "{}", op),
48            Sym::Symbol(sym) => write!(f, "{}", sym),
49            Sym::Eof => write!(f, "<eof>"),
50        }
51    }
52}
53
54/// Operator types for expressions.
55///
56/// This enum represents all the operators supported in EventQL, including
57/// arithmetic, comparison, and logical operators.
58///
59/// # Operator Precedence
60///
61/// From highest to lowest precedence:
62/// 1. Unary: `+`, `-`, `NOT`
63/// 2. Multiplicative: `*`, `/`
64/// 3. Additive: `+`, `-`
65/// 4. Comparison: `<`, `<=`, `>`, `>=`, `==`, `!=`
66/// 5. Logical: `AND`, `OR`, `XOR`
67#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, Serialize)]
68pub enum Operator {
69    /// Addition operator `+`
70    Add,
71    /// Subtraction operator `-`
72    Sub,
73    /// Multiplication operator `*`
74    Mul,
75    /// Division operator `/`
76    Div,
77    /// Equality operator `==`
78    Eq,
79    /// Inequality operator `!=`
80    Neq,
81    /// Less than operator `<`
82    Lt,
83    /// Less than or equal operator `<=`
84    Lte,
85    /// Greater than operator `>`
86    Gt,
87    /// Greater than or equal operator `>=`
88    Gte,
89    /// Logical AND operator
90    And,
91    /// Logical OR operator
92    Or,
93    /// Logical XOR operator
94    Xor,
95    /// Logical NOT operator
96    Not,
97    /// Containment (`array CONTAINS value`)
98    Contains,
99    /// Type conversion (`e.foo as STRING`)
100    As,
101}
102
103impl Display for Operator {
104    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
105        match self {
106            Operator::Add => write!(f, "+"),
107            Operator::Sub => write!(f, "-"),
108            Operator::Mul => write!(f, "*"),
109            Operator::Div => write!(f, "/"),
110            Operator::Eq => write!(f, "=="),
111            Operator::Neq => write!(f, "!="),
112            Operator::Lt => write!(f, "<"),
113            Operator::Lte => write!(f, "<="),
114            Operator::Gt => write!(f, ">"),
115            Operator::Gte => write!(f, ">="),
116            Operator::And => write!(f, "AND"),
117            Operator::Or => write!(f, "OR"),
118            Operator::Xor => write!(f, "XOR"),
119            Operator::Not => write!(f, "NOT"),
120            Operator::Contains => write!(f, "CONTAINS"),
121            Operator::As => write!(f, "AS"),
122        }
123    }
124}
125
126/// Structural symbols used in EventQL syntax.
127///
128/// These symbols define the structure of expressions and queries,
129/// such as parentheses for grouping, brackets for arrays, and braces for records.
130#[derive(Clone, Debug, Copy, PartialEq, Eq, Serialize, Deserialize)]
131pub enum Symbol {
132    /// Opening parenthesis `(`
133    OpenParen,
134    /// Closing parenthesis `)`
135    CloseParen,
136    /// Dot `.` (for field access)
137    Dot,
138    /// Comma `,` (for separating list items)
139    Comma,
140    /// Colon `:` (for record field definitions)
141    Colon,
142    /// Opening bracket `[`
143    OpenBracket,
144    /// Closing bracket `]`
145    CloseBracket,
146    /// Opening brace `{`
147    OpenBrace,
148    /// Closing brace `}`
149    CloseBrace,
150}
151
152impl Display for Symbol {
153    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
154        match self {
155            Symbol::OpenParen => write!(f, "("),
156            Symbol::CloseParen => write!(f, ")"),
157            Symbol::Dot => write!(f, "."),
158            Symbol::Comma => write!(f, ","),
159            Symbol::Colon => write!(f, ":"),
160            Symbol::OpenBracket => write!(f, "["),
161            Symbol::CloseBracket => write!(f, "]"),
162            Symbol::OpenBrace => write!(f, "{{"),
163            Symbol::CloseBrace => write!(f, "}}"),
164        }
165    }
166}
167
168/// Type alias for text with position tracking.
169///
170/// Used internally by the lexer for tracking positions during tokenization.
171pub type Text<'a> = LocatedSpan<&'a str>;
172
173/// A token with position information.
174///
175/// Tokens are the output of lexical analysis and the input to syntactic analysis.
176/// Each token contains a symbol (its type and value) along with its position
177/// in the source code.
178#[derive(Debug, Clone, Copy, Serialize)]
179pub struct Token<'a> {
180    /// The symbol (type and value) of this token
181    pub sym: Sym<'a>,
182    /// Line number where this token appears (1-indexed)
183    pub line: u32,
184    /// Column number where this token appears (1-indexed)
185    pub col: u32,
186}