fix(parser): Rework function call parsing

This commit is contained in:
Guillem L. Jara
2026-04-30 01:06:04 +02:00
parent 1609ff1b1c
commit 8384183a4d
2 changed files with 24 additions and 16 deletions
+1 -4
View File
@@ -120,9 +120,6 @@ pub enum Token<'a> {
#[regex("(?&identifier)", Identifier::without_namespace)]
#[regex(r"(?&identifier)::(?&identifier)", Identifier::with_namespace)]
Identifier(Identifier<'a>),
#[regex(r"(?&identifier)\(", Identifier::without_namespace)]
#[regex(r"(?&identifier)::(?&identifier)\(", Identifier::with_namespace)]
FunctionCall(Identifier<'a>),
#[token("+", accept_expression)]
Plus,
#[token("-", accept_expression)]
@@ -231,7 +228,7 @@ pub enum LexingError {
UnexpectedEof,
}
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Identifier<'a> {
pub namespace: Option<&'a str>,
pub literal: &'a str,
+23 -12
View File
@@ -367,7 +367,8 @@ impl<'a> Parser<'a> {
#[tracing::instrument]
fn parse_case(&mut self, lex: &mut Lexer<'a>) -> Result<Atom<'a>> {
lex.expect(&Token::Case)?;
let value = self.parse_atom(lex)?;
let next = lex.expect_next()?;
let value = self.parse_atom(lex, next)?;
lex.expect(&Token::Colon)?;
match value {
Atom::Variable(_) => Err(ParsingError::UnexpectedToken),
@@ -485,10 +486,16 @@ impl<'a> Parser<'a> {
} else {
return Err(ParsingError::UnexpectedToken);
}
} else if lex.peek_with(|t| matches!(t, Token::FunctionCall(_))) {
self.parse_function_call(lex)?
} else {
Expr::leaf(self.parse_atom(lex)?)
let next = lex.expect_next()?;
if let Token::Identifier(name) = next
&& lex.peek_is(&Token::OpenParent)
{
// TODO: use spans to check there is no space between ident, (.
self.parse_function_call(lex, name.qualify(self.namespace))?
} else {
Expr::leaf(self.parse_atom(lex, next)?)
}
};
while let Some(next) = lex.peek() {
@@ -592,12 +599,14 @@ impl<'a> Parser<'a> {
}
#[tracing::instrument]
fn parse_function_call(&mut self, lex: &mut Lexer<'a>) -> Result<Expr<'a>> {
let Token::FunctionCall(ident) = lex.expect_next()? else {
return Err(ParsingError::UnexpectedToken);
};
fn parse_function_call(
&mut self,
lex: &mut Lexer<'a>,
name: Identifier<'a>,
) -> Result<Expr<'a>> {
lex.expect(&Token::OpenParent)?;
let expr = ExprNode::FunctionCall(
ident.qualify(self.namespace),
name,
self.parse_arguments(lex, |t| t == &Token::ClosedParent)?,
);
lex.expect(&Token::ClosedParent)?;
@@ -605,12 +614,14 @@ impl<'a> Parser<'a> {
}
#[tracing::instrument]
fn parse_atom(&self, lex: &mut Lexer<'a>) -> Result<Atom<'a>> {
match lex.expect_next()? {
fn parse_atom(&self, lex: &mut Lexer<'a>, token: Token<'a>) -> Result<Atom<'a>> {
match token {
Token::Number(n) => Ok(Atom::Number(n)),
Token::String(s) => Ok(Atom::String(s)),
Token::Regex(r) => Ok(Atom::Regex(r)),
Token::Identifier(a) => Ok(Atom::Variable(a.qualify(self.namespace).into())),
Token::Identifier(a) if !lex.peek_is(&Token::OpenParent) => {
Ok(Atom::Variable(a.qualify(self.namespace).into()))
}
Token::NrVariable => Ok(Variable::Nr.into()),
Token::NfVariable => Ok(Variable::Nf.into()),
Token::FsVariable => Ok(Variable::Fs.into()),