我正试图在Atom中为我正在使用的玩具语言制作语法突出显示器。我正在定义上下文无关语法的阶段。我一直在逐步构建它,并一路编写测试。当我为for in循环添加语法时,因为标识符以“ in”开头,所以它无法解析标识符。这是现在的语法(很抱歉粘贴了这么多代码,但是我不知道可能有什么关系,所以我只添加了整个内容):
module.exports = grammar({
name: 'MooLang',
rules: {
source_file: $ => repeat($._declaration),
_declaration: $ => choice(
$.variable_declaration,
$._statement
),
variable_declaration: $ => seq(
choice('var', 'let'),
$.identifier,
optional(seq(
':', $._type
)),
optional(seq(
'=', $._expression
)),
$.eol
),
_statement: $ => choice(
$.for_statement,
$.expression_statement
),
for_statement: $ => prec(0, seq(
'for',
'(',
choice(
$.variable_declaration,
$.expression_statement,
),
'in',
$._expression,
')',
$._statement
)),
expression_statement: $ => prec(1, seq(
$._expression,
$.eol
)),
_expression: $ => choice(
$.assignment,
$.comparison_expression,
$.addition_expression,
$.multiplication_expression,
$.unary_expression,
prec(5, $.primary),
prec(-1, $._type) // TODO:(Casey) Remove this
),
assignment: $ => prec.right(0, seq(
$.identifier,
'=',
$._expression
)),
comparison_expression: $ => prec.left(1, seq(
$._expression,
choice('<', '<=', '>', '>=', '==', '!='),
$._expression
)),
addition_expression: $ => prec.left(2, seq(
$._expression,
choice('+', '-'),
$._expression
)),
multiplication_expression: $ => prec.left(3, seq(
$._expression,
choice('*', '/', '%'),
$._expression
)),
unary_expression: $=> prec.right(4, seq(
choice('!', '-'),
$.primary
)),
_type: $ => choice(
$.primitive_type,
$.list_type,
$.map_type
),
primitive_type: $ => choice(
'bool', 'string',
'int8', 'int16', 'int32', 'int64',
'uint8', 'uint16', 'uint32', 'uint64',
'float32', 'float64'
),
list_type: $ => seq(
'[',
$._type,
']'
),
map_type: $ => seq(
'{',
$._type,
':',
$._type,
'}'
),
primary: $ => choice(
$.bool_literal,
$.list_literal,
$.map_literal,
$.parenthetical_expression,
$.identifier,
$.number
),
bool_literal: $ => choice('true', 'false'),
list_literal: $ => seq(
'[',
optional(seq(
$._expression,
repeat(seq(
',',
$._expression
)),
optional(','),
)),
']'
),
map_literal: $ => seq(
'{',
optional(seq(
$._expression,
':',
$._expression,
repeat(seq(
',',
$._expression,
':',
$._expression,
)),
)),
'}'
),
parenthetical_expression: $ => seq(
'(',
$._expression,
')'
),
identifier: $ => prec(99, /[a-zA-Z_][a-zA-Z0-9_]*/),
number: $ => prec(99, /\d+(_\d+)*(\.\d+)?/),
eol: $ => '\n'
}
});
以下是相关测试:
==================
Identifier Tests
==================
13india
---
(source_file
(expression_statement (primary (number)) (MISSING))
(expression_statement (primary (identifier)) (eol))
)
==================
For Tests
==================
for (var a in people) a + 1
---
(source_file
(for_statement (variable_declaration (identifier)) (primary (identifier)) (expression_statement (addition_expression (primary (identifier)) (primary (number))) (eol)))
)
直到我为所有标识符测试通过的for循环添加语法,但现在我得到以下输出:
我的猜测是它发现一个意外的'd',因为它认为这是'in'关键字。但是我不知道为什么会这样认为,因为它与for循环不符。