class AdLint::Cpp::Lexer
Constants
- GROUP_DIRECTIVE_RE
Attributes
content[R]
Public Class Methods
new(src, traits)
click to toggle source
# 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
Public Instance Methods
discard_heading_comments()
click to toggle source
# 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_token()
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 141 def notify_unterminated_block_comment(loc) on_unterminated_block_comment.invoke(loc) end
skip_group()
click to toggle source
# 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_token()
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 78 def top_token @top_token ? @top_token : (@top_token = self.next_token) end
transit(next_state)
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 125 def transit(next_state) @state = next_state end
Private Instance Methods
scan_block_comment(cont)
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 176 def scan_block_comment(cont) comment = "" nest_depth = 0 until cont.empty? loc = cont.location case when nest_depth == 0 && cont.scan(/\/\*/) nest_depth = 1 comment += "/*" when nest_depth > 0 && cont.check(/\/\*\//) comment += cont.scan(/\//) when nest_depth > 0 && cont.check(/\/\*/) nest_depth += 1 comment += cont.scan(/\/\*/) notify_nested_block_comment_found(loc) when cont.scan(/\*\//) comment += "*/" break when nest_depth == 0 return nil else if scanned = cont.scan(/.*?(?=\/\*|\*\/)/m) comment += scanned else notify_unterminated_block_comment(loc) end end end comment end
scan_line_comment(cont)
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 207 def scan_line_comment(cont) cont.scan(/\/\/.*?(?=\n)/) end
scan_until_next_directive_or_comment(cont)
click to toggle source
# File lib/adlint/cpp/lexer.rb, line 162 def scan_until_next_directive_or_comment(cont) until cont.empty? cont.scan(/.*?(?=#{GROUP_DIRECTIVE_RE}|"|'|\/\*|\/\/)/m) case when cont.check(/"/) Language::C::scan_string_literal(cont) when cont.check(/'/) Language::C::scan_char_constant(cont) else break end end end