Class: Foxtail::Syntax::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/foxtail/syntax/parser.rb,
lib/foxtail/syntax/parser/ast.rb,
lib/foxtail/syntax/parser/stream.rb,
lib/foxtail/syntax/parser/ast/junk.rb,
lib/foxtail/syntax/parser/ast/span.rb,
lib/foxtail/syntax/parser/ast/term.rb,
lib/foxtail/syntax/parser/ast/comment.rb,
lib/foxtail/syntax/parser/ast/message.rb,
lib/foxtail/syntax/parser/ast/pattern.rb,
lib/foxtail/syntax/parser/ast/variant.rb,
lib/foxtail/syntax/parser/parse_error.rb,
lib/foxtail/syntax/parser/ast/resource.rb,
lib/foxtail/syntax/parser/ast/attribute.rb,
lib/foxtail/syntax/parser/ast/base_node.rb,
lib/foxtail/syntax/parser/ast/placeable.rb,
lib/foxtail/syntax/parser/ast/annotation.rb,
lib/foxtail/syntax/parser/ast/identifier.rb,
lib/foxtail/syntax/parser/ast/syntax_node.rb,
lib/foxtail/syntax/parser/ast/base_comment.rb,
lib/foxtail/syntax/parser/ast/base_literal.rb,
lib/foxtail/syntax/parser/ast/text_element.rb,
lib/foxtail/syntax/parser/ast/group_comment.rb,
lib/foxtail/syntax/parser/ast/call_arguments.rb,
lib/foxtail/syntax/parser/ast/named_argument.rb,
lib/foxtail/syntax/parser/ast/number_literal.rb,
lib/foxtail/syntax/parser/ast/string_literal.rb,
lib/foxtail/syntax/parser/ast/term_reference.rb,
lib/foxtail/syntax/parser/ast/resource_comment.rb,
lib/foxtail/syntax/parser/ast/message_reference.rb,
lib/foxtail/syntax/parser/ast/select_expression.rb,
lib/foxtail/syntax/parser/ast/function_reference.rb,
lib/foxtail/syntax/parser/ast/variable_reference.rb

Overview

Ruby equivalent of fluent.js FluentParser Translates TypeScript parsing logic to Ruby

Defined Under Namespace

Modules: AST Classes: Indent, ParseError, Stream

Instance Method Summary collapse

Constructor Details

#initialize(with_spans: true) ⇒ Parser

Create a new Parser instance

Parameters:

  • with_spans (Boolean) (defaults to: true)

    Whether to include span information in AST nodes (default: true)



17
18
19
# File 'lib/foxtail/syntax/parser.rb', line 17

def initialize(with_spans: true)
  @with_spans = with_spans
end

Instance Method Details

#parse(source) ⇒ Parser::AST::Resource

Main entry point - parse FTL source into AST

Parameters:

  • source (String)

    FTL source text to parse

Returns:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/foxtail/syntax/parser.rb', line 27

def parse(source)
  ps = Stream.new(source)
  ps.skip_blank_block

  entries = []
  last_comment = nil

  while ps.current_char
    entry = get_entry_or_junk(ps)
    blank_lines = ps.skip_blank_block

    # Regular Comments require special logic. Comments may be attached to
    # Messages or Terms if they are followed immediately by them. However
    # they should parse as standalone when they're followed by AST::Junk.
    # Consequently, we only attach Comments once we know that the AST::Message
    # or the AST::Term parsed successfully.
    if entry.is_a?(AST::Comment) && blank_lines.length == 0 && ps.current_char
      # Stash the comment and decide what to do with it in the next pass.
      last_comment = entry
      next
    end

    if last_comment
      if entry.is_a?(AST::Message) || entry.is_a?(AST::Term)
        entry.comment = last_comment
        if @with_spans && entry.span && last_comment.span
          entry.span.start = last_comment.span.start
        end
      else
        entries << last_comment
      end
      # In either case, the stashed comment has been dealt with; clear it.
      last_comment = nil
    end

    # No special logic for other types of entries.
    entries << entry
  end

  res = AST::Resource.new(entries)
  if @with_spans
    res.add_span(0, ps.index)
  end

  res
end

#parse_entry(source) ⇒ Parser::AST::Message, ...

Parse the first AST::Message or AST::Term in source

Parameters:

  • source (String)

    FTL source text to parse

Returns:



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/foxtail/syntax/parser.rb', line 77

def parse_entry(source)
  ps = Stream.new(source)
  ps.skip_blank_block

  while ps.current_char == "#"
    skipped = get_entry_or_junk(ps)
    return skipped if skipped.is_a?(AST::Junk)

    ps.skip_blank_block
  end

  get_entry_or_junk(ps)
end

#with_spans?Boolean

Returns Whether to include span information in AST nodes.

Returns:

  • (Boolean)

    Whether to include span information in AST nodes



22
# File 'lib/foxtail/syntax/parser.rb', line 22

def with_spans? = @with_spans