mirror of
https://github.com/uutils/awk.git
synced 2026-06-10 16:15:04 -07:00
Revert "parser, lexer: solve function call ambiguity"
This reverts commit 5213c1e6fb.
This commit is contained in:
+6
-9
@@ -126,12 +126,9 @@ pub enum Token<'a> {
|
||||
RlengthVariable,
|
||||
#[token("ENVIRON", accept_expression)]
|
||||
EnvironVariable,
|
||||
#[regex("(?&identifier)", |lex| Identifier::without_namespace::<0>(lex))]
|
||||
#[regex(r"(?&identifier)::(?&identifier)", |lex| Identifier::with_namespace::<0>(lex))]
|
||||
#[regex("(?&identifier)", Identifier::without_namespace)]
|
||||
#[regex(r"(?&identifier)::(?&identifier)", Identifier::with_namespace)]
|
||||
Identifier(Identifier<'a>),
|
||||
#[regex(r"(?&identifier)\(", |lex| Identifier::without_namespace::<1>(lex))]
|
||||
#[regex(r"(?&identifier)::(?&identifier)\(", |lex| Identifier::with_namespace::<1>(lex))]
|
||||
FunctionCall(Identifier<'a>),
|
||||
#[token("+", accept_expression)]
|
||||
Plus,
|
||||
#[token("-", accept_expression)]
|
||||
@@ -379,19 +376,19 @@ fn parse_float(lex: &mut Lexer<'_>) -> f64 {
|
||||
}
|
||||
|
||||
impl<'a> Identifier<'a> {
|
||||
fn without_namespace<const TRIM: usize>(lex: &mut Lexer<'a>) -> Self {
|
||||
fn without_namespace(lex: &mut Lexer<'a>) -> Self {
|
||||
Self {
|
||||
namespace: None,
|
||||
literal: parse_ident(lex, ..lex.slice().len() - TRIM),
|
||||
literal: parse_ident(lex, ..),
|
||||
}
|
||||
}
|
||||
|
||||
fn with_namespace<const TRIM: usize>(lex: &mut Lexer<'a>) -> Self {
|
||||
fn with_namespace(lex: &mut Lexer<'a>) -> Self {
|
||||
// SAFETY: The regex matching ensures it is present and well-formed.
|
||||
let separator = unsafe { memchr(b':', lex.slice()).unwrap_unchecked() };
|
||||
Self {
|
||||
namespace: Some(parse_ident(lex, ..separator)),
|
||||
literal: parse_ident(lex, separator + 2..lex.slice().len() - TRIM),
|
||||
literal: parse_ident(lex, separator + 2..),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -190,10 +190,8 @@ impl TokenExt for Token<'_> {
|
||||
fn is_expr_start(&self) -> bool {
|
||||
self.is_atom()
|
||||
|| self.is_prefix_op()
|
||||
|| matches!(
|
||||
self,
|
||||
Token::OpenParent | Token::FunctionCall(_) | Token::Getline
|
||||
)
|
||||
|| self == &Token::OpenParent
|
||||
|| self == &Token::Getline
|
||||
}
|
||||
fn is_place(&self) -> bool {
|
||||
matches!(
|
||||
|
||||
+15
-13
@@ -465,17 +465,7 @@ impl<'a> Parser<'a> {
|
||||
|
||||
#[tracing::instrument]
|
||||
fn parse_function(&mut self, lex: &mut Lexer<'a>) -> Result<()> {
|
||||
let name = match lex.expect_next()? {
|
||||
Token::FunctionCall(ident) => ident,
|
||||
Token::Identifier(ident) => {
|
||||
lex.expect(&Token::OpenParent, |span| {
|
||||
ParsingError::NoFunctionSignature(span, ident.literal.to_string())
|
||||
})?;
|
||||
ident
|
||||
}
|
||||
_ => return Err(ParsingError::ExpectedIdentifier(lex.span())),
|
||||
}
|
||||
.qualify(self.namespace);
|
||||
let name = lex.expect_identifier()?.qualify(self.namespace);
|
||||
let args = self.parse_signature(lex, &name)?;
|
||||
lex.consume(&Token::Newline);
|
||||
let body = self.parse_body(lex)?;
|
||||
@@ -491,6 +481,9 @@ impl<'a> Parser<'a> {
|
||||
name: &Identifier<'a>,
|
||||
) -> Result<Vec<'a, Identifier<'a>>> {
|
||||
let mut args = Vec::new_in(self.arena);
|
||||
lex.expect(&Token::OpenParent, |s| {
|
||||
ParsingError::NoFunctionSignature(s, name.to_string())
|
||||
})?;
|
||||
|
||||
if lex.consume(&Token::ClosedParent) {
|
||||
return Ok(args);
|
||||
@@ -574,7 +567,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
} else {
|
||||
let next = lex.expect_next()?;
|
||||
if let Token::FunctionCall(name) = 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), lex.span())?
|
||||
} else {
|
||||
Expr::leaf(self.parse_atom(lex, next)?)
|
||||
@@ -695,6 +691,10 @@ impl<'a> Parser<'a> {
|
||||
name: Identifier<'a>,
|
||||
span: Span,
|
||||
) -> Result<Expr<'a>> {
|
||||
lex.expect(&Token::OpenParent, ParsingError::ExpectedOpeningParenthesis)?;
|
||||
if lex.span().start != span.end {
|
||||
return Err(ParsingError::FunctionCallSeparatedIdent(span));
|
||||
}
|
||||
let expr = ExprNode::FunctionCall(
|
||||
name,
|
||||
self.parse_arguments(lex, |t| t == &Token::ClosedParent)?,
|
||||
@@ -724,7 +724,9 @@ impl<'a> Parser<'a> {
|
||||
#[tracing::instrument]
|
||||
fn get_place(&self, lex: &mut Lexer<'a>, token: Token<'a>) -> Option<Variable<'a>> {
|
||||
match token {
|
||||
Token::Identifier(a) => Some(a.qualify(self.namespace).into()),
|
||||
Token::Identifier(a) if !lex.peek_is(&Token::OpenParent) => {
|
||||
Some(a.qualify(self.namespace).into())
|
||||
}
|
||||
Token::NrVariable => Some(Variable::Nr),
|
||||
Token::NfVariable => Some(Variable::Nf),
|
||||
Token::FsVariable => Some(Variable::Fs),
|
||||
|
||||
Reference in New Issue
Block a user