Estou tentando entender como funciona o awk do busybox, então estou analisando o padrão e acerto uma coisa estranha que não entendo completamente por que é legal. Padrão ( https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html , na seção User-Defined Functions
) afirma que
Ao invocar uma função, nenhum espaço em branco pode ser colocado entre o nome da função e o parêntese de abertura.
A gramática mostrada mais adiante é prefixada com:
Essa sintaxe formal deve ter precedência sobre a descrição da sintaxe de texto anterior.
non_unary_expr : '(' expr ')'
| '!' expr
...
| FUNC_NAME '(' expr_list_opt ')'
/* no white space allowed before '(' */
| BUILTIN_FUNC_NAME '(' expr_list_opt ')'
| BUILTIN_FUNC_NAME
A gramática é completamente a mesma para ambos BUILTIN_FUNC_NAME
e FUNC_NAME
. No entanto, apesar disso, ele se comporta de maneira diferente para funções de usuário e internas:
+$echo | awk -P '{ print length() 1 }'
01
+$echo | awk -P '{ print length () 1 }'
01
+$echo | awk -P 'function foo() { return 0 } ; { print foo() 1 }'
01
+$echo | awk -P 'function foo() { return 0 } ; { print foo () 1 }'
awk: cmd. line:1: error: function `foo' called with space between name and `(',
or used as a variable or an array
awk: cmd. line:1: function foo() { return 0 } ; { print foo () 1 }
awk: cmd. line:1: ^ syntax error
awk: cmd. line:1: function foo() { return 0 } ; { print foo () 1 }
awk: cmd. line:1: ^ syntax error
Qual parte da gramática especifica esse comportamento?
Verifique a definição de
FUNC_NAME
na mesma especificação que você está citando:Portanto, a diferença já é feita no lexer , e uma palavra como
foo
se transformará em aNAME
, não emFUNC_NAME
token, quando não for seguida imediatamente por a(
.