我正在尝试创建一个非常基本的
.sublime-syntax
文件来了解基于 YAML 的定义如何工作并最终创建完整的定义(该语言是 UnrealScript 的旧版本 - 这种语言的定义已经存在,但我正在做这更多的是一个学习练习)。
我要解决的第一件事是变量的声明,它可以以几种不同的形式存在:
var int myInt;
var int myIntA, myIntB, myIntC;
var() int myInt;
var(foo) int myInt;
我的语法文件当前如下所示:
%YAML 1.2
---
name: UnrealScript
file_extensions:
- uc
scope: source.uscript
variables:
valid_variable_name: '[a-zA-Z_][a-zA-Z_0-9]{0,}'
valid_type_name: '{{valid_variable_name}}'
contexts:
main:
- match: ;
scope: punctuation.terminator.statement.empty.uscript
- match: '(?i)\bvar'
scope: storage.variable.var.uscript
push:
- meta_scope: meta.variable.assignment
- match: \(
scope: punctuation.variable.property.begin.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.parameter.uscript
- match: ''
pop: 1
- match: \)
scope: punctuation.variable.property.end.uscript
- match: '{{valid_type_name}}(?=\s+)'
scope: storage.type.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.other.readwrite.uscript
pop: 1
- match: ;
pop: 1
这似乎正确地突出显示了内容,但假设我开始输入此内容并且尚未添加分号:
var int myInt, somethingElse
^^^^^^^^^^^^^
变量名
somethingElse
被分配了storage.type.uscript
范围,但我希望它被分配variable.other.readwrite.uscript
- 我错过了什么?
旁注:我知道命名上下文,但在此示例中使用匿名上下文。
之所以将
somethingElse
的作用域设置为 storage.type.uscript
,是因为它仍然处于元作用域 meta.variable.assignment
的上下文中。 (顺便说一句,如果上下文被命名,讨论会更容易......)所以它认为 {{valid_type_name}}(?=\s+)
与 somethingElse
匹配(假设后面有一个换行符,并且不完全在 EOF 处键入)。
这里的简单解决方案是正确地在逗号后面设置变量的范围 - 因此,不要在分配范围后弹出
variable.other.readwrite.uscript
,而只在分号处弹出。
%YAML 1.2
---
name: UnrealScript
file_extensions:
- uc
scope: source.uscript
variables:
valid_variable_name: '[a-zA-Z_][a-zA-Z_0-9]{0,}'
valid_type_name: '{{valid_variable_name}}'
contexts:
main:
- match: ;
scope: punctuation.terminator.statement.empty.uscript
- match: '(?i)\bvar'
scope: storage.variable.var.uscript
push:
- meta_scope: meta.variable.assignment
- match: \(
scope: punctuation.variable.property.begin.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.parameter.uscript
- match: ''
pop: 1
- match: \)
scope: punctuation.variable.property.end.uscript
- match: '{{valid_type_name}}(?=\s+)'
scope: storage.type.uscript
push:
- match: '{{valid_variable_name}}'
scope: variable.other.readwrite.uscript
- match: ','
scope: punctuation.separator.sequence.uscript
- match: (?=;)
pop: 1
- match: ;
scope: punctuation.terminator.uscript
pop: 1