gsd-parser 0.6.0

Parser for PROFIBUS GSD files (Generic Station Description)
Documentation
COMMENT = _{ ";" ~ (!NEWLINE ~ ANY)* }

WHITESPACE = _{ " " | "\t" | ("\\" ~ NEWLINE) }

any_line = @{ !start ~ (!NEWLINE ~ ANY)* ~ NEWLINE }
any_text = @{ any_line* }

start = @{ "#" ~ ^"Profibus_DP" ~ NEWLINE }

number = _{ hex_number | dec_number }
hex_number = @{ "0x" ~ ASCII_HEX_DIGIT+ }
dec_number = @{ "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }

number_list = { number ~ (("," ~ number) | ("\\" ~ NEWLINE) | ("," ~ "\\" ~ NEWLINE ~ number))* }

family_ident = @{ number ~ "@" ~ (!NEWLINE ~ ANY)* }

string_literal = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }

identifier_part = _{ ASCII_ALPHANUMERIC | "_" | "." }
identifier = @{ identifier_part+ }


prm_text = {
    ^"PrmText" ~ "=" ~ number ~ NEWLINE+ ~
    (prm_text_value ~ NEWLINE+)+ ~
    ^"EndPrmText"
}
prm_text_value = { ^"Text" ~ "(" ~ number ~ ")" ~ "=" ~ string_literal }

ext_user_prm_data = {
    ^"ExtUserPrmData" ~ "=" ~ number ~ string_literal ~ NEWLINE+ ~
    prm_data_type_name ~ number ~ (prm_data_value_range | prm_data_value_set)? ~ NEWLINE+ ~
    prm_text_ref? ~
    prm_data_changeable? ~
    prm_data_visible? ~
    ^"EndExtUserPrmData"
}
bit_area = { ^"BitArea" ~ "(" ~ number ~ "-" ~ number ~ ")" }
bit = { ^"Bit" ~ "(" ~ number ~ ")" }
prm_data_type_name = { bit | bit_area | identifier }
prm_data_value_range = { number ~ "-" ~ number }
prm_data_value_set = { number ~ ("," ~ number)* }
prm_text_ref = { ^"Prm_Text_Ref" ~ "=" ~ number ~ NEWLINE+ }
prm_data_changeable = { ^"Changeable" ~ "=" ~ number ~ NEWLINE+ }
prm_data_visible = { ^"Visible" ~ "=" ~ number ~ NEWLINE+ }

module = {
    ^"Module" ~ "=" ~ string_literal ~ number_list ~ NEWLINE+ ~
    (setting ~ NEWLINE+)* ~
    module_reference? ~
    (setting ~ NEWLINE+)* ~
    (data_area ~ NEWLINE+)* ~
    (setting ~ NEWLINE+)* ~
    ^"EndModule"
}
module_reference = {number ~ NEWLINE+}
data_area = {
    ^"Data_Area_Beg" ~ NEWLINE+ ~
    (setting ~ NEWLINE+)* ~
    ^"Data_Area_End"
}

slot_definition = {
    ^"SlotDefinition" ~ NEWLINE+ ~
    (slot ~ NEWLINE+)* ~
    ^"EndSlotDefinition"
}
slot = { ^"Slot" ~ "(" ~ number ~ ")" ~ "=" ~ string_literal ~ number ~ ( slot_value_range | slot_value_set ) }
slot_value_range = { number ~ "-" ~ number }
slot_value_set = { number ~ ("," ~ number)* }

unit_diag_type = {
    ^"UnitDiagType" ~ "=" ~ number ~ NEWLINE+ ~
    (!^"EndUnitDiagType" ~ ANY)* ~
    ^"EndUnitDiagType"
}

unit_diag_area = {
    ^"Unit_Diag_Area" ~ "=" ~ number ~ "-" ~ number ~ NEWLINE+ ~
    (unit_diag_area_value ~ NEWLINE+)+ ~
    ^"Unit_Diag_Area_End"
}
unit_diag_area_value = { ^"Value" ~ "(" ~ number ~ ")" ~ "=" ~ string_literal }

version_dl_definition = {
    ^"Version_Firmware_Download" ~ NEWLINE+ ~
    (!^"End_Version_Firmware_Download" ~ ANY)* ~
    ^"End_Version_Firmware_Download"
}

physical_interface = {
    ^"Physical_Interface" ~ "=" ~ number ~ NEWLINE+ ~
    (!^"End_Physical_Interface" ~ ANY)* ~
    ^"End_Physical_Interface"
}

jokerblock_type = {
    ^"Jokerblock_Type" ~ "=" ~ number ~ NEWLINE+ ~
    (!^"End_Jokerblock_Type" ~ ANY)* ~
    ^"End_Jokerblock_Type"
}

setting_value = _{
    string_literal |
    (&(number ~ ",") ~ number_list) |
    (&(number ~ "@") ~ family_ident) |
    number
}
setting = { identifier ~ ( "(" ~ number ~ ")" )? ~ "=" ~ setting_value }

statement = _{
      prm_text
    | ext_user_prm_data
    | module
    | slot_definition
    | unit_diag_type
    | unit_diag_area
    | version_dl_definition
    | physical_interface
    | jokerblock_type
    | setting
}

gsd = { SOI ~ any_text ~ start ~ NEWLINE* ~ statement ~ (NEWLINE+ ~ statement)* ~ NEWLINE* ~ EOI }