Skip to content

Commit a238cf5

Browse files
committed
parse global
1 parent 83c6e35 commit a238cf5

File tree

3 files changed

+534
-0
lines changed

3 files changed

+534
-0
lines changed

GLOBAL_KEYWORD_CHANGES.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Lua 5.5 `global` 关键字语法支持 - 变更摘要
2+
3+
## 概述
4+
为 Lua Language Server 添加了对 Lua 5.5 新增的 `global` 关键字的完整语法解析支持。
5+
6+
## 修改的文件
7+
- `script/parser/compile.lua`
8+
9+
## 主要变更
10+
11+
### 1. 关键字识别 (第 1391-1420 行)
12+
`isKeyWord` 函数中添加了对 `global` 关键字的处理:
13+
- 仅在 Lua 5.5 中将 `global` 视为关键字
14+
- 其他版本中可作为普通标识符使用
15+
-`goto` 关键字的处理方式一致
16+
17+
### 2. 解析函数 (第 3130-3274 行)
18+
新增 `parseGlobal` 函数,支持三种语法形式:
19+
20+
**a) 全局函数声明**
21+
```lua
22+
global function funcName() end
23+
```
24+
25+
**b) 全局变量声明(带属性)**
26+
```lua
27+
global x -- 单个变量
28+
global <const> y -- 带属性
29+
global a, b, c -- 多个变量
30+
global <const> x, <close> y, z -- 混合属性
31+
```
32+
33+
**c) 全局所有变量**
34+
```lua
35+
global * -- 所有后续变量为全局
36+
global <const> * -- 带属性的全局所有
37+
```
38+
39+
### 3. 语法分发 (第 4117-4119 行)
40+
`parseAction` 函数中添加了 global 关键字的检查和分发:
41+
```lua
42+
if token == 'global' and isKeyWord('global', Tokens[Index + 3]) then
43+
return parseGlobal()
44+
end
45+
```
46+
47+
## 生成的 AST 节点
48+
49+
### setglobal 节点
50+
用于全局变量和函数声明:
51+
```lua
52+
{
53+
type = 'setglobal',
54+
start = <position>,
55+
finish = <position>,
56+
[1] = <variable_name>,
57+
attrs = <optional_attributes>, -- 可选的属性列表
58+
value = <optional_value> -- 对于函数声明
59+
}
60+
```
61+
62+
### globalall 节点
63+
用于 `global *` 声明:
64+
```lua
65+
{
66+
type = 'globalall',
67+
start = <position>,
68+
finish = <position>,
69+
attrs = <optional_attributes>
70+
}
71+
```
72+
73+
## 兼容性
74+
75+
- **Lua 5.5**: `global` 是保留关键字
76+
- **Lua 5.4 及以下**: `global` 可用作标识符
77+
78+
## 测试
79+
80+
要测试此功能:
81+
1. 设置 Lua 版本为 5.5
82+
2. 使用包含 global 声明的代码
83+
3. 验证语法高亮和解析正确性
84+
85+
## 下一步
86+
87+
此实现仅完成了语法解析。完整的功能还需要:
88+
- 语义分析(作用域、引用)
89+
- 类型推断
90+
- 代码补全
91+
- 诊断检查
92+
- 文档生成
93+
94+
详见 `GLOBAL_KEYWORD_IMPLEMENTATION.md`

GLOBAL_KEYWORD_IMPLEMENTATION.md

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# Lua 5.5 `global` 关键字实现
2+
3+
## 概述
4+
5+
本次修改为 Lua Language Server 添加了对 Lua 5.5 新增的 `global` 关键字的语法解析支持。
6+
7+
## 语法规则
8+
9+
根据 Lua 5.5 的语法规范,`global` 关键字支持以下三种形式:
10+
11+
### 1. 全局函数声明
12+
```lua
13+
global function funcName()
14+
-- function body
15+
end
16+
```
17+
18+
### 2. 全局变量声明(带属性)
19+
```lua
20+
-- 单个变量
21+
global x
22+
23+
-- 带属性的变量
24+
global <const> y
25+
26+
-- 多个变量
27+
global a, b, c
28+
29+
-- 带属性的多个变量
30+
global <const> x, <close> y, z
31+
```
32+
33+
### 3. 全局所有变量声明
34+
```lua
35+
-- 声明所有后续变量为全局
36+
global *
37+
38+
-- 带属性的全局所有变量
39+
global <const> *
40+
```
41+
42+
## 实现细节
43+
44+
### 1. 关键字识别 (`isKeyWord` 函数)
45+
46+
`compile.lua``isKeyWord` 函数中添加了对 `global` 关键字的处理:
47+
48+
```lua
49+
if word == 'global' then
50+
if State.version == 'Lua 5.5' then
51+
return true
52+
end
53+
return false
54+
end
55+
```
56+
57+
类似于 `goto` 关键字的处理方式,`global` 仅在 Lua 5.5 版本中被视为关键字。在其他版本中,它可以作为普通标识符使用。
58+
59+
### 2. 解析函数 (`parseGlobal` 函数)
60+
61+
创建了新的 `parseGlobal` 函数来处理三种不同的 global 语法形式:
62+
63+
- **全局函数**: 调用 `parseFunction` 并将返回的名称类型设置为 `'setglobal'`
64+
- **全局变量**: 解析 attnamelist,支持前置和后置属性
65+
- **全局所有**: 创建特殊的 `'globalall'` 节点
66+
67+
### 3. 语法分发 (`parseAction` 函数)
68+
69+
`parseAction` 函数中添加了对 `global` 关键字的检查:
70+
71+
```lua
72+
if token == 'global' and isKeyWord('global', Tokens[Index + 3]) then
73+
return parseGlobal()
74+
end
75+
```
76+
77+
## 生成的 AST 节点类型
78+
79+
### setglobal 节点
80+
用于全局变量和全局函数声明:
81+
```lua
82+
{
83+
type = 'setglobal',
84+
start = <position>,
85+
finish = <position>,
86+
[1] = <variable_name>,
87+
attrs = <optional_attributes>,
88+
value = <optional_function_or_value>
89+
}
90+
```
91+
92+
### globalall 节点
93+
用于 `global *` 声明:
94+
```lua
95+
{
96+
type = 'globalall',
97+
start = <position>,
98+
finish = <position>,
99+
attrs = <optional_attributes>
100+
}
101+
```
102+
103+
## 版本兼容性
104+
105+
- **Lua 5.5**: `global` 作为关键字,启用完整的语法解析
106+
- **Lua 5.4 及更早版本**: `global` 作为普通标识符,可以用作变量名
107+
108+
## 测试建议
109+
110+
要测试此实现,需要:
111+
112+
1. 设置项目的 Lua 版本为 5.5
113+
2. 创建包含 global 声明的测试文件
114+
3. 验证语法高亮和错误检查是否正常工作
115+
116+
示例测试代码:
117+
```lua
118+
-- 这些在 Lua 5.5 中应该正常解析
119+
global function test()
120+
print("hello")
121+
end
122+
123+
global x
124+
global <const> y
125+
global a, b, c
126+
global *
127+
128+
-- 这在非 Lua 5.5 版本中应该可以正常使用
129+
local global = 10 -- 'global' 作为变量名
130+
```
131+
132+
## 修改的文件
133+
134+
本次实现仅修改了一个文件:
135+
136+
- `script/parser/compile.lua`
137+
138+
### 修改内容总结
139+
140+
1. **isKeyWord 函数** (约第 1391 行)
141+
- 添加了对 `global` 关键字的版本检查
142+
- 仅在 Lua 5.5 中将其识别为关键字
143+
144+
2. **parseGlobal 函数** (约第 3123 行,新增)
145+
- 完整实现了三种 global 语法的解析
146+
- 处理属性(attrib)的解析和关联
147+
- 支持多变量声明的解析
148+
149+
3. **parseAction 函数** (约第 4044 行)
150+
- 添加了 global 关键字的分发逻辑
151+
- 使用 `isKeyWord` 检查确保版本正确性
152+
153+
## 使用示例
154+
155+
在支持 Lua 5.5 的环境中,以下代码将被正确解析:
156+
157+
```lua
158+
-- 示例 1: 声明全局函数
159+
global function myGlobalFunction()
160+
return 42
161+
end
162+
163+
-- 示例 2: 声明全局变量
164+
global x
165+
166+
-- 示例 3: 声明带常量属性的全局变量
167+
global <const> PI = 3.14159
168+
169+
-- 示例 4: 声明多个全局变量
170+
global width, height, depth
171+
172+
-- 示例 5: 声明带不同属性的多个全局变量
173+
global <const> MAX_SIZE, <close> file, counter
174+
175+
-- 示例 6: 声明所有后续变量为全局
176+
global *
177+
x = 1 -- x 是全局变量
178+
y = 2 -- y 是全局变量
179+
180+
-- 示例 7: 带属性的全局所有
181+
global <const> *
182+
```
183+
184+
## 后续工作
185+
186+
当前实现仅包括语法解析层面的支持。完整的功能还需要:
187+
188+
1. **语义分析支持**
189+
- 变量作用域处理
190+
- 引用关系跟踪
191+
- `globalall` 声明的作用域影响
192+
193+
2. **类型推断支持**
194+
- 全局变量的类型推断
195+
- 属性(const/close)的类型约束
196+
197+
3. **代码补全支持**
198+
- global 关键字的补全
199+
- 全局变量的智能提示
200+
201+
4. **诊断和错误检查**
202+
- 重复声明检查
203+
- 常量修改检查
204+
- close 属性的正确性验证
205+
206+
5. **文档生成支持**
207+
- 全局变量的文档注释
208+
- API 文档生成
209+
210+
这些功能需要在以下模块中进行相应的修改:
211+
- `script/vm/*` - 虚拟机和语义分析
212+
- `script/core/completion.lua` - 代码补全
213+
- `script/core/diagnostics.lua` - 诊断
214+
- `script/core/hover.lua` - 悬停提示
215+
- 等等
216+
217+
## 兼容性说明
218+
219+
此实现完全向后兼容:
220+
221+
- **Lua 5.5**: `global` 是保留关键字,按新语法解析
222+
- **Lua 5.4 及以下**: `global` 是普通标识符,可以用作变量名或函数名
223+
224+
示例:
225+
```lua
226+
-- 在 Lua 5.4 中,这是有效的:
227+
local global = "这是一个变量"
228+
function global()
229+
return "这是一个函数"
230+
end
231+
232+
-- 在 Lua 5.5 中,上述代码会报错,因为 global 是关键字
233+
```
234+
235+
## 技术细节
236+
237+
### attnamelist 的解析
238+
239+
attnamelist 的语法定义为:
240+
```
241+
attnamelist ::= [attrib] Name [attrib] {',' Name [attrib]}
242+
```
243+
244+
这意味着属性可以出现在变量名之前或之后。我们的实现支持这两种情况:
245+
246+
```lua
247+
-- 属性在前
248+
global <const> x
249+
250+
-- 属性在后
251+
global x <const>
252+
253+
-- 混合使用
254+
global <const> x <close>, y, <const> z
255+
```
256+
257+
### AST 节点设计
258+
259+
所有 global 声明都会生成适当的 AST 节点,与现有的 `local` 声明保持一致的结构,便于后续的语义分析和其他处理。

0 commit comments

Comments
 (0)