Class: Ecu::LabelList::DcmLexer

Inherits:
Object
  • Object
show all
Defined in:
lib/ecu/interfaces/dcm/dcm_lexer.rb

Constant Summary collapse

KEYWORDS =
[
  "FUNKTIONEN", "FESTWERT", "FESTWERTEBLOCK", "KENNLINIE", "GRUPPENKENNLINIE", "FESTKENNLINIE",
  "KENNFELD", "GRUPPENKENNFELD", "FESTKENNFELD", "STUETZSTELLENVERTEILUNG",
  "FKT",
  "ST/X", "ST/Y", "WERT", "ST_TX/X", "ST_TX/Y", "TEXT",
  "FUNKTION",
  "EINHEIT_X", "EINHEIT_Y", "EINHEIT_W",
  "LANGNAME", "DISPLAYNAME",
  "END",
].freeze
HEADER =
"KONSERVIERUNG_FORMAT 2.0"
WHITESPACE =
%r{ [ \t]+ }x
NEWLINE =
%r{ \r\n|\n }x
COMMENT =
%r{ ^\*.*$ }x
DIMENSIONS_SEP =
%r{ @ }x
QUOTED_TEXT =
%r{ "[^"]*" }x
IDENTIFIER =
%r{ [A-Za-z][A-Za-z0-9_\.]* }x
UNSIGNED_INT =
%r{ [0]|[1-9][0-9]* }x
INT =
%r{ [-]?#{UNSIGNED_INT} }x
FLOAT_EXP =
%r{ [eE][+-]?[0-9]+ }x
FLOAT =
%r{
     [-+]?
     (?:
        #{UNSIGNED_INT}?[.][0-9]+#{FLOAT_EXP} |      # 1.23e10 or .45e3
        #{UNSIGNED_INT}          #{FLOAT_EXP} |      # 3e4
        #{UNSIGNED_INT}?[.][0-9]+             |      # 7.3 or .50
        #{UNSIGNED_INT} [.][0-9]*                    # 3.02 or 9.
     )
}x
KW_RE =
/#{Regexp.union(KEYWORDS.sort)}\b/
KW_TABLE =

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc) ⇒ DcmLexer

Returns a new instance of DcmLexer.



9
10
11
12
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 9

def initialize(doc)
  @doc  = doc
  @scan = StringScanner.new(doc)
end

Instance Attribute Details

#docObject (readonly)

Returns the value of attribute doc.



8
9
10
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 8

def doc
  @doc
end

Instance Method Details

#linenoObject



84
85
86
87
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 84

def lineno
  @doc.byteslice(0, @scan.pos).count("\n") +
    (@scan.beginning_of_line? ? 0 : 1)
end

#next_tokenObject



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
73
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 48

def next_token
  # This is a hot path during DCM parsing. Make sure to optimize
  # here are far as possible

  @scan.skip(WHITESPACE)

  return if @scan.eos?

  case @doc.getbyte(@scan.pos)
  when 10, 13          then @scan.skip(NEWLINE)        && :NEWLINE        # \n \r
  when 34              then @scan.skip(QUOTED_TEXT)    && :QUOTED_TEXT    # "
  when 42              then @scan.skip(COMMENT)        && :COMMENT        # *
  when 64              then @scan.skip(DIMENSIONS_SEP) && :DIMENSIONS_SEP # @
  when 43, 45, 46, 48..57                                                 # + - . 0-9
    if    @scan.skip(FLOAT) then :FLOAT
    elsif @scan.skip(INT)   then :INT
    else  @scan.getch;           :UNKNOWN_CHAR
    end
  else
    if    s = @scan.scan(KW_RE)    then KW_TABLE[s]
    elsif @scan.skip(HEADER)       then :HEADER
    elsif @scan.skip(IDENTIFIER)   then :IDENTIFIER
    else  @scan.getch;                  :UNKNOWN_CHAR
    end
  end
end

#quoted_valueObject

Extracts quoted-text content without surrounding quotes in a single allocation.



80
81
82
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 80

def quoted_value
  @scan.string.byteslice(@scan.pos - @scan.matched_size + 1, @scan.matched_size - 2)
end

#token_valueObject



75
76
77
# File 'lib/ecu/interfaces/dcm/dcm_lexer.rb', line 75

def token_value
  @scan.matched
end