Class: AdLint::Cpp::Lexer

Inherits:
Object
  • Object
show all
Extended by:
Pluggable
Defined in:
lib/adlint/cpp/lexer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Pluggable

def_plugin

Constructor Details

#initialize(src, traits) ⇒ Lexer

Returns a new instance of Lexer.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/adlint/cpp/lexer.rb', line 40

def initialize(src, traits)
  src.on_cr_at_eol_found += lambda { |loc|
    on_cr_at_eol_found.invoke(loc)
  }
  src.on_eof_mark_at_eof_found += lambda { |loc|
    on_eof_mark_at_eof_found.invoke(loc)
  }
  src.on_eof_newline_not_found += method(:notify_eof_newline_not_found)

  tab_width  = traits.of_project.coding_style.tab_width
  @content   = SourceContent.lazy_new(src, tab_width)
  @state     = Initial.new(self)
  @top_token = nil
end

Instance Attribute Details

#contentObject (readonly)

Returns the value of attribute content.



55
56
57
# File 'lib/adlint/cpp/lexer.rb', line 55

def content
  @content
end

Instance Method Details

#discard_heading_commentsObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/adlint/cpp/lexer.rb', line 105

def discard_heading_comments
  case
  when @content.check(/\/\*/)
    loc = @content.location
    comment = scan_block_comment(@content)
    unless comment.empty?
      notify_block_comment_found(comment, loc)
      return true
    end
  when @content.check(/\/\//)
    loc = @content.location
    comment = scan_line_comment(@content)
    unless comment.empty?
      notify_line_comment_found(comment, loc)
      return true
    end
  end
  false
end

#next_tokenObject



69
70
71
72
73
74
75
76
# File 'lib/adlint/cpp/lexer.rb', line 69

def next_token
  if @top_token
    tok = @top_token
    @top_token = nil
    return tok
  end
  @state.next_token
end

#notify_block_comment_found(comment, loc) ⇒ Object



129
130
131
# File 'lib/adlint/cpp/lexer.rb', line 129

def notify_block_comment_found(comment, loc)
  on_block_comment_found.invoke(comment, loc)
end

#notify_eof_newline_not_found(loc) ⇒ Object



145
146
147
# File 'lib/adlint/cpp/lexer.rb', line 145

def notify_eof_newline_not_found(loc)
  on_eof_newline_not_found.invoke(loc)
end

#notify_illformed_newline_escape_found(loc) ⇒ Object



153
154
155
# File 'lib/adlint/cpp/lexer.rb', line 153

def notify_illformed_newline_escape_found(loc)
  on_illformed_newline_escape_found.invoke(loc)
end

#notify_line_comment_found(comment, loc) ⇒ Object



133
134
135
# File 'lib/adlint/cpp/lexer.rb', line 133

def notify_line_comment_found(comment, loc)
  on_line_comment_found.invoke(comment, loc)
end

#notify_nested_block_comment_found(loc) ⇒ Object



137
138
139
# File 'lib/adlint/cpp/lexer.rb', line 137

def notify_nested_block_comment_found(loc)
  on_nested_block_comment_found.invoke(loc)
end

#notify_unlexable_char_found(char, loc) ⇒ Object



149
150
151
# File 'lib/adlint/cpp/lexer.rb', line 149

def notify_unlexable_char_found(char, loc)
  on_unlexable_char_found.invoke(char, loc)
end

#notify_unterminated_block_comment(loc) ⇒ Object



141
142
143
# File 'lib/adlint/cpp/lexer.rb', line 141

def notify_unterminated_block_comment(loc)
  on_unterminated_block_comment.invoke(loc)
end

#skip_groupObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/adlint/cpp/lexer.rb', line 82

def skip_group
  group_depth = 1
  until @content.empty?
    scan_until_next_directive_or_comment(@content)

    case
    when @content.check(/\/\*|\/\//)
      discard_heading_comments
    when @content.check(/[ \t]*#[ \t]*(?:if|ifdef|ifndef|asm)\b/)
      group_depth += 1
      @content.scan(/.*?\n/)
    when @content.check(/[ \t]*#[ \t]*(?:else|elif)\b/)
      return true if group_depth == 1
      @content.scan(/.*?\n/)
    when @content.check(/[ \t]*#[ \t]*(?:endif|endasm)\b/)
      group_depth -= 1
      return true if group_depth == 0
      @content.scan(/.*?\n/)
    end
  end
  false
end

#top_tokenObject



78
79
80
# File 'lib/adlint/cpp/lexer.rb', line 78

def top_token
  @top_token ? @top_token : (@top_token = self.next_token)
end

#transit(next_state) ⇒ Object



125
126
127
# File 'lib/adlint/cpp/lexer.rb', line 125

def transit(next_state)
  @state = next_state
end