# -*- coding: utf-8 -*- # # frozen_string_literal: true module Rouge module Lexers class BPF < RegexLexer title "BPF" desc "BPF bytecode syntax" tag 'bpf' TYPE_KEYWORDS = %w( u8 u16 u32 u64 ll ).join('|') MISC_KEYWORDS = %w( be16 be32 be64 exit lock ).join('|') state :root do # Calls to helpers rule %r/(call)(\s+)(\d+)/i do groups Keyword, Text::Whitespace, Literal::Number::Integer end # Unconditional jumps rule %r/(goto)(\s*)(\+\d+)?(\s*)(?)/i do groups Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label end # Conditional jumps rule %r/(if)(\s+)(r\d+)(\s*)([s!=<>]+)(\s*)(0x\h+|[-]?\d+)(\s*)(goto)(\s*)(\+\d+)?(\s*)(?)/i do groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label end rule %r/(if)(\s+)(r\d+)(\s*)([s!=<>]+)(\s*)(r\d+)(\s*)(goto)(\s*)(\+\d+)?(\s*)(?)/i do groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Name, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label end # Dereferences rule %r/(\*)(\s*)(\()(#{TYPE_KEYWORDS})(\s*)(\*)(\))/i do groups Operator, Text::Whitespace, Punctuation, Keyword::Type, Text::Whitespace, Operator, Punctuation push :address end # Operators rule %r/[+-\/\*&|><^s]{0,3}=/i, Operator # Registers rule %r/([+-]?)(r\d+)/i do groups Punctuation, Name end # Comments rule %r/\/\//, Comment::Single, :linecomment rule %r/\/\*/, Comment::Multiline, :multilinescomment rule %r/#{MISC_KEYWORDS}/i, Keyword # Literals and global objects (maps) refered by name rule %r/(0x\h+|[-]?\d+)(\s*)(ll)?/i do groups Literal::Number, Text::Whitespace, Keyword::Type end rule %r/(\w+)(\s*)(ll)/i do groups Name, Text::Whitespace, Keyword::Type end # Labels rule %r/(\w+)(\s*)(:)/i do groups Name::Label, Text::Whitespace, Punctuation end rule %r{.}m, Text end state :address do # Address is offset from register rule %r/(\()(r\d+)(\s*)([+-])(\s*)(\d+)(\))/i do groups Punctuation, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number::Integer, Punctuation pop! end # Address is array subscript rule %r/(\w+)(\[)(\d+)(\])/i do groups Name, Punctuation, Literal::Number::Integer, Punctuation pop! end rule %r/(\w+)(\[)(r\d+)(\])/i do groups Name, Punctuation, Name, Punctuation pop! end end state :linecomment do rule %r/\n/, Comment::Single, :pop! rule %r/.+/, Comment::Single end state :multilinescomment do rule %r/\*\//, Comment::Multiline, :pop! rule %r/([^\*\/]+)/, Comment::Multiline rule %r/([\*\/])/, Comment::Multiline end end end end