我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Lua的语法是无歧义的吗

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Lua的语法是无歧义的吗

这篇文章主要介绍“Lua的语法是无歧义的吗”,在日常操作中,相信很多人在Lua的语法是无歧义的吗问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Lua的语法是无歧义的吗”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

首先定义如下几个函数:

function foo(a) print("foo print",a) return a end function goo(a) print("goo print",a) return a end function hoo(a) print("hoo print",a) return a end

试看这一段代码:

foo(goo)

(hoo)(1979)

如果试图编译执行上面这段程序,那么解释器就会报告 "ambiguous syntax (function call x new  statement) near '(' "  这样的错误。为什么呢?或许写程序的人原本的意思就是***行foo(goo)为一个单独的函数调用语句(statement),而第二行(hoo) (1979)又为另一个单独的函数调用语句(Lua中语句之间的分隔符——分号并非必需,而是可选的)。但是不要忘记了foo(goo)(hoo)是一个 语法上完全合法的函数调用形式(在编译过程中换行符作为空白符会被忽略掉),foo(goo)(hoo)(1979)也可以成为一个完整的函数调用语句。 这样的话,编译器就无法知道程序员的真正意图了。

我们可以再深入到编译过程里头一点看看。Lua语法的形式定义(转换成BNF标准形式)包含如下几个产生式:

(1) stat -> functioncall (语句的产生式)

(2) prefixexp -> functioncall (前缀表达式的产生式)

(3) functioncall -> prefixexp args

| prefixexp ':' Name args (函数调用的产生式)

可以发现,functioncall既可以被规约(reduce)为stat,也可以被规约成prefixexp,(1)和(2)两个产生式发生了冲突,编译器不知道用哪一个对foo(goo)进行规约,所以便出现了错误。

其实要解决这个问题歧义问题也很简单,在***行后面加一个语句分隔符——分号,编译器就会把代码编译成两个独立的语句。或者把两行合并成一行, 那么foo(goo)(hoo)(1979)就被看作是一个完整的函数调用(其实此时仍然是有歧义的,但是Lua5.04通过优先选择prefixexp  -> functioncall进行规约解决了二义性)。

实际上,还有另外3种情况也会引起歧义:

-- prefixexp -> functioncall 与 -- exp -> functioncall 冲突。 -- 编译器不知道该把foo(goo)解释成表达式(exp)还是前缀表达式 local v = foo(goo) (hoo)(1979) -- exp -> var 与 prefixexp -> var 冲突 -- 第二行的变量(var)m不知道该被看成表达式还是前缀表达式 m = foo local v = m (goo)(1979) -- prefixexp -> '(' exp ')' 与 -- exp -> '(' exp ')' 冲突 -- 不知道该把(t.fn)看成表达式还是前缀表达式 t = {fn = foo} local v = (t.fn) (goo)(1979)

到此,关于“Lua的语法是无歧义的吗”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Lua的语法是无歧义的吗

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++ 函数重载中歧义调用的处理方法是什么?

歧义调用发生在编译器无法确定调用哪个重载函数时。处理方法包括:为每个重载函数提供唯一的函数签名(参数类型和数量)。使用显式类型转换强制调用正确的函数,如果一个重载函数的参数类型更适合给定调用的参数。如果编译器无法解决歧义调用,将产生错误消息
C++ 函数重载中歧义调用的处理方法是什么?
2024-04-13

c语言宏定义无替换文本的方法是什么

在 C 语言中,宏定义的目的就是为了替换文本。然而,如果希望定义一个不替换文本的宏,可以使用宏定义的特殊形式,即 "宏定义的参数为空"。具体的方法如下:```c#define MACRO()```这样定义的宏没有参数,也没有任何文本替换,调
2023-10-11

C#中的变量定义语法是什么

这篇文章主要介绍“C#中的变量定义语法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C#中的变量定义语法是什么”文章能帮助大家解决问题。C# 中的变量定义C# 中变量定义的语法:
2023-06-17

C语言宏定义的用法是什么

C语言宏定义是一种预处理指令,用于在程序编译之前进行文本替换。宏定义可以将一个标识符(通常是一个函数或常量)替换为指定的代码段或值。宏定义的一般形式是:#define 宏名 替换文本宏名是标识符,替换文本可以是一个常量、表达式、语句或其他代
2023-10-11

c语言定义字符的方法是什么

在 C 语言中,字符类型使用 char 关键字进行定义。要定义一个字符变量,可以按照以下格式:char myChar = A;在上面的示例中,myChar 是一个字符变量,它被初始化为大写字母’A’。注意,在 C 语言中,字符常量用单引号
c语言定义字符的方法是什么
2024-03-13

c语言常量定义的方法是什么

在C语言中,常量可以使用#define预处理器指令或使用const关键字来定义。使用#define定义常量:#define PI 3.14159#define MAX_NUM 100使用const关键字定义常量:const double
c语言常量定义的方法是什么
2024-03-07

c语言转义字符的用法是什么

C语言中的转义字符用来表示一些特殊的字符,这些字符在普通的字符常量或字符串中无法直接表示。转义字符以反斜杠(\)开头,后面跟着一个或多个字符,用于表示特定的含义。以下是一些常用的转义字符及其用法:\n:换行符\t:制表符\r:回车符
2023-10-27

c语言中函数的定义方法是什么

在C语言中,函数的定义通常包含以下几个部分:1. 返回类型:函数可以有不同的返回类型,如int、float、void等,用来表示函数返回的数据类型。2. 函数名:用来标识函数的名称,可以根据需要自定义。3. 参数列表:函数可以接受一定数量的
2023-09-29

go语言的匿名函数定义方法是什么

go语言的匿名函数定义方法是“func(参数列表)(返回参数列表){函数体}”,其实匿名函数的定义就是没有名字的普通函数定义。匿名函数完全可以当作一个类型,可以直接赋值,可以赋值给变量,可以当作实参或者返回值进行使用,当然也可以直接进行调用。
2023-05-14

c语言转义字符的使用方法是什么

在C语言中,转义字符以反斜杠(\)开头,用于表示一些特殊字符或控制字符,例如换行符(\n)、制表符(\t)、回车符(\r)、退格符(\b)等。转义字符的使用方法是在需要输入特殊字符时,在字符前加上反斜杠即可。例如,要在字符串中输出换行符,可
c语言转义字符的使用方法是什么
2024-03-01

C语言宏的定义与使用方法是什么

本文小编为大家详细介绍“C语言宏的定义与使用方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言宏的定义与使用方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、C语言中的宏定义#define
2023-06-30

c语言变长数组定义的方法是什么

在C语言中,变长数组(Variable Length Arrays,VLA)可以通过指定数组大小为变量来定义。变长数组的大小在编译时确定,可以根据程序运行时的需要动态调整大小。变长数组的定义方法如下所示:int main() {int
c语言变长数组定义的方法是什么
2024-03-13

c语言函数的定义与调用方法是什么

C语言函数的定义和调用方法如下:1. 函数的定义:在C语言中,函数的定义包括函数的返回类型、函数名、参数列表和函数体。函数的定义一般写在main函数之前或者使用函数原型声明。函数定义的一般形式如下:返回类型 函数名(参数列表) {函数体}例
2023-08-18

c语言中全局变量定义的方法是什么

在C语言中,全局变量可以在函数外部定义。以下是全局变量定义的方法:1. 在所有函数的外部定义变量,这样变量就可以在程序的任何地方访问。```cint globalVariable; // 全局变量定义```2. 在定义变量的同时进行初始化。
2023-09-29

C语言结构体嵌套定义的方法是什么

在C语言中,可以通过在结构体中嵌套其他结构体来定义一个结构体的成员。具体的方法如下:1. 首先定义一个结构体类型,可以包含多个成员,其中某些成员可以是其他结构体类型。```cstruct struct_name {member1_type
2023-08-15

C语言之结构体定义typedef struct的方法是什么

本篇内容介绍了“C语言之结构体定义typedef struct的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!结构体定义 type
2023-07-05

C++中右值引用与移动语义的方法是什么

今天小编给大家分享一下C++中右值引用与移动语义的方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。意义充分利用临时对
2023-07-05

编程热搜

目录