语言结构和“内置"语言有什么区别?PHP 中的函数? [英] What is the difference between a language construct and a "built-in" function in PHP?

查看:41
本文介绍了语言结构和“内置"语言有什么区别?PHP 中的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道includeissetrequireprintecho,还有一些不是函数而是语言结构.

I know that include, isset, require, print, echo, and some others are not functions but language constructs.

其中一些语言结构需要括号,其他则不需要.

Some of these language constructs need parentheses, others don't.

require 'file.php';
isset($x);

有些有返回值,有些没有.

Some have a return value, others do not.

print 'foo'; //1
echo  'foo'; //no return value

那么语言结构和内置函数之间的内部区别是什么?

So what is the internal difference between a language construct and a built-in function?

推荐答案

(这比我预期的要长;请耐心等待.)

(This is longer than I intended; please bear with me.)

大多数语言都由一种称为语法"的东西组成:该语言由几个定义明确的关键字组成,您可以用该语言构建的完整表达式范围是根据该语法构建的.

Most languages are made up of something called a "syntax": the language is comprised of several well-defined keywords, and the complete range of expressions that you can construct in that language is built up from that syntax.

例如,假设您有一个简单的四函数算术语言",它只接受一位数的整数作为输入并完全忽略运算顺序(我告诉过你这是一种简单的语言).该语言可以由语法定义:

For example, let's say you have a simple four-function arithmetic "language" that only takes single-digit integers as input and completely ignores order of operations (I told you it was a simple language). That language could be defined by the syntax:

// The | means "or" and the := represents definition
$expression := $number | $expression $operator $expression
$number := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
$operator := + | - | * | /

根据这三个规则,您可以构建任意数量的个位数输入算术表达式.然后,您可以为此语法编写一个解析器,将任何有效输入分解为其组件类型($expression$number$operator) 并处理结果.例如,表达式 3 + 4 * 5 可以分解如下:

From these three rules, you can build any number of single-digit-input arithmetic expressions. You can then write a parser for this syntax that breaks down any valid input into its component types ($expression, $number, or $operator) and deals with the result. For example, the expression 3 + 4 * 5 can be broken down as follows:

// Parentheses used for ease of explanation; they have no true syntactical meaning
$expression = 3 + 4 * 5
            = $expression $operator (4 * 5) // Expand into $exp $op $exp
            = $number $operator $expression // Rewrite: $exp -> $num
            = $number $operator $expression $operator $expression // Expand again
            = $number $operator $number $operator $number // Rewrite again

现在我们有一个完全解析的语法,在我们定义的语言中,用于原始表达式.有了这个,我们就可以通过写一个解析器,找出$number $operator $number 的所有组合的结果,当我们只有一个$时,吐出一个结果号码离开.

Now we have a fully parsed syntax, in our defined language, for the original expression. Once we have this, we can go through and write a parser to find the results of all the combinations of $number $operator $number, and spit out a result when we only have one $number left.

请注意,在我们原始表达式的最终解析版本中没有留下 $expression 结构.这是因为 $expression 总是可以简化为我们语言中其他事物的组合.

Take note that there are no $expression constructs left in the final parsed version of our original expression. That's because $expression can always be reduced to a combination of other things in our language.

PHP 大体相同:语言结构被认为等同于我们的 $number$operator.它们不能简化为其他语言结构;相反,它们是构建语言的基本单位.函数和语言结构之间的主要区别在于:解析器直接处理语言结构.它将函数简化为语言结构.

PHP is much the same: language constructs are recognized as the equivalent of our $number or $operator. They cannot be reduced into other language constructs; instead, they're the base units from which the language is built up. The key difference between functions and language constructs is this: the parser deals directly with language constructs. It simplifies functions into language constructs.

语言构造可能需要也可能不需要括号的原因以及一些具有返回值而另一些没有的原因完全取决于 PHP 解析器实现的特定技术细节.我不太熟悉解析器的工作原理,所以我无法具体解决这些问题,但请想象一下以这样开头的语言:

The reason that language constructs may or may not require parentheses and the reason some have return values while others don't depends entirely on the specific technical details of the PHP parser implementation. I'm not that well-versed in how the parser works, so I can't address these questions specifically, but imagine for a second a language that starts with this:

$expression := ($expression) | ...

实际上,这种语言可以自由地使用它找到的任何表达式并去掉周围的括号.PHP(在这里我使用纯猜测)可能会为其语言结构采用类似的东西: print("Hello") 可能会减少到 print "Hello" 之前它被解析,反之亦然(语言定义可以添加括号也可以去掉它们).

Effectively, this language is free to take any expressions it finds and get rid of the surrounding parentheses. PHP (and here I'm employing pure guesswork) may employ something similar for its language constructs: print("Hello") might get reduced down to print "Hello" before it's parsed, or vice-versa (language definitions can add parentheses as well as get rid of them).

这就是为什么你不能重新定义像 echoprint 这样的语言结构的根源:它们被有效地硬编码到解析器中,而函数被映射到一组语言构造和解析器允许您在编译或运行时更改该映射以替换您自己的一组语言构造或表达式.

This is the root of why you can't redefine language constructs like echo or print: they're effectively hardcoded into the parser, whereas functions are mapped to a set of language constructs and the parser allows you to change that mapping at compile- or runtime to substitute your own set of language constructs or expressions.

归根结底,构造和表达式之间的内部区别在于:语言构造由解析器理解和处理.内置函数虽然由语言提供,但在解析之前被映射和简化为一组语言结构.

At the end of the day, the internal difference between constructs and expressions is this: language constructs are understood and dealt with by the parser. Built-in functions, while provided by the language, are mapped and simplified to a set of language constructs before parsing.

更多信息:

  • Backus-Naur form, the syntax used to define formal languages (yacc uses this form)

阅读其他一些答案,人们提出了很好的观点.其中:

Reading through some of the other answers, people make good points. Among them:

  • 调用内置语言比调用函数更快.这是真的,即使只是轻微的,因为 PHP 解释器不需要在解析之前将该函数映射到它的语言内置等价物.但是,在现代机器上,差异可以忽略不计.
  • 一种内置语言可以绕过错误检查.这可能是也可能不是,这取决于每个内置函数的 PHP 内部实现.诚然,函数通常具有更高级的错误检查和内置函数所没有的其他功能.
  • 语言结构不能用作函数回调.这是真的,因为构造不是函数.它们是独立的实体.当您编写内置函数时,您并不是在编写带有参数的函数——内置函数的语法由解析器直接处理,并被识别为内置函数,而不是函数.(如果您考虑具有一流函数的语言,这可能更容易理解:实际上,您可以将函数作为对象传递.使用内置函数则无法做到这一点.)
  • A language builtin is faster to call than a function. This is true, if only marginally, because the PHP interpreter doesn't need to map that function to its language-builtin equivalents before parsing. On a modern machine, though, the difference is fairly negligible.
  • A language builtin bypasses error-checking. This may or may not be true, depending on the PHP internal implementation for each builtin. It is certainly true that more often than not, functions will have more advanced error-checking and other functionality that builtins don't.
  • Language constructs can't be used as function callbacks. This is true, because a construct is not a function. They're separate entities. When you code a builtin, you're not coding a function that takes arguments - the syntax of the builtin is handled directly by the parser, and is recognized as a builtin, rather than a function. (This may be easier to understand if you consider languages with first-class functions: effectively, you can pass functions around as objects. You can't do that with builtins.)

这篇关于语言结构和“内置"语言有什么区别?PHP 中的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆