对于语法中断标识符

时间:2019-03-24 06:41:54

标签: syntax-highlighting atom-editor context-free-grammar

我正试图在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循环添加语法,但现在我得到以下输出:

Testing Error Output

我的猜测是它发现一个意外的'd',因为它认为这是'in'关键字。但是我不知道为什么会这样认为,因为它与for循环不符。

0 个答案:

没有答案