Skip to main content

Validator for Mitsubishi MELSEC iQ-R device and constant strings used in GX Works3

Project description

iqr_device_validator

PyPI version Python versions License: MIT

Mitsubishi MELSEC iQ-R シリーズのデバイス文字列・定数を検証する Python ライブラリです。GX Works3 で使われる表記 (X0, D100.A, K4M0, J1\W10, SA\D100, K1234, T#1h30m など) を正規表現+構文木でパースし、設定可能範囲の上限修飾子の組み合わせ可否をチェックします。

A validator for device & constant strings used in Mitsubishi MELSEC iQ-R PLC programs (GX Works3 syntax). Validates not just the form of a device reference, but also whether the device number is within the configurable range and whether modifiers (digit/bit/index/local/indirect) are legal for that device kind.


Features

  • General devicesX, Y, M, L, B, F, SB, V, S, T, ST, LT, LST, C, LC, D, W, SW, FX, FY, FD, SM, SD, Z, LZ, R, ZR, RD, P, I, N
  • Direct access I/ODX, DY (e.g. DX10, DY25, K4DX0)
  • SFC devicesBL (block device), TR (transition device), and the in-block step reference form BL<n>\S<m> (e.g. BL0, BL10\S100, TR5)
  • Link direct devicesJ<n>\<dev> (e.g. J1\W10, J239\K4B0)
  • Unit access devicesU<n>\G<addr>, U3E<n>\G<addr>, U3E<n>\HG<addr>
  • Safety devicesSA\X, SA\Y, SA\M, SA\B, SA\T, SA\ST, SA\C, SA\D, SA\W, SA\SM, SA\SD with the standard safety-program restrictions enforced (no index modification, no indirect, limited local prefix)
  • All modifiers — bit (.A), digit (K4), index (Z/LZ/ZZ), indirect (@), local (#)
  • Continuity check for digit specification: K8X2FF0 is rejected because the 32 bits would extend past X2FFF
  • ConstantsTRUE/FALSE, decimal (K123/123), hex (HFF/16#FF), binary (2#01101010), octal (8#377), real (E1.234/1.0E6), string ('ABC'), wstring ("ABC"), time (T#1d2h3m4s5ms)
  • String escape sequences$$ (literal $), $'/$" (escaped quotes), $L/$N/$T/$R/$P (LF/newline/tab/CR/FF, case-insensitive), and $<HH> (ASCII hex byte). Decoded value reflects the actual bytes, e.g. 'A$LB'"A\nB".
  • Yen-mark normalization\, ¥, , are all accepted as the path separator (common in Japanese docs)
  • No dependencies — pure standard library, single file

Installation

pip install iqr_device_validator

Requires Python 3.10 or later.


Quick start

from iqr_device_validator import validate

# Devices
print(validate("D100.A").ok)         # True   (D100, bit A specification)
print(validate("X3000").ok)          # False  (out of range; max is X2FFF)
print(validate("K8X2FF0").ok)        # False  (K8 would extend past X2FFF)
print(validate("@D10Z2.A").ok)       # True   (indirect + index + bit)
print(validate("DX10").ok)           # True   (direct access input)
print(validate("DY5E").ok)           # True   (direct access output)
print(validate("@DX0").ok)           # False  (indirect not allowed on direct I/O)
print(validate("BL10\\S100").ok)     # True   (SFC: step 100 of block 10)
print(validate("BL320\\S0").ok)      # False  (block out of range)
print(validate("SA\\D100").ok)       # True   (safety device)
print(validate("@SA\\D0").ok)        # False  (safety devices forbid @)

# Constants
print(validate("K1234").ok)          # True   (decimal constant)
print(validate("HFF").ok)            # True   (hex constant)
print(validate("E1.234").ok)         # True   (real constant)
print(validate("T#1h30m").ok)        # True   (time constant)
print(validate("'ABC'").ok)          # True   (string constant)
print(validate("'A$LB'").value)      # "A\nB" (escape decoded)
print(validate("'$X'").ok)           # False  (invalid escape)

API

validate(text: str) -> ValidationResult

The single entry point. Returns a ValidationResult dataclass:

@dataclass
class ValidationResult:
    ok: bool                       # True if valid
    category: str                  # "device" | "constant"
    error: str                     # human-readable message when ok=False

    # --- device fields (when category == "device") ---
    kind: str                      # "simple" | "link_direct" | "un_g" | "u3e_g" | "safety"
    prefix: str                    # device prefix, e.g. "D", "J\\W", "SA\\D"
    number: int                    # parsed device number
    bit_no: Optional[int]          # 0..15 for word-bit specs
    digits: Optional[int]          # 1..8 for digit specs
    digit_end_no: Optional[int]    # base + digits*4 - 1
    network: Optional[int]         # network No. for J\
    unit: Optional[int]            # unit No. for U\G
    cpu: Optional[int]             # CPU No. for U3E\G
    area: Optional[str]            # "G" | "HG" for U3E
    indirect: bool                 # @ prefix present
    local: bool                    # # prefix present
    safety: bool                   # SA\ prefix present
    index: Optional[IndexMod]      # index modification, if any

    # --- constant fields (when category == "constant") ---
    const_type: str                # "bool"|"dec"|"hex"|"bin"|"oct"|"real"|"string"|"wstring"|"time"
    value: object                  # parsed value (int/float/bool/str/dict)

Example: lint a list of operands

from iqr_device_validator import validate

operands = ["X0", "D100", "K4M0", "X3000", "Z24", "@FX0", "K1234", "'hello'"]
for op in operands:
    r = validate(op)
    if r.ok:
        print(f"OK   {op:10s}  ({r.category} / {r.kind or r.const_type})")
    else:
        print(f"FAIL {op:10s}  {r.error}")

Output:

OK   X0          (device / simple)
OK   D100        (device / simple)
OK   K4M0        (device / simple)
FAIL X3000       device number out of range (got X3000, max X2FFF)
FAIL Z24         device number out of range (got Z24, max Z23)
FAIL @FX0        indirect (@) not supported by FX
OK   K1234       (constant / dec)
OK   'hello'     (constant / string)

What gets validated

Device range

Each device's max settable count is taken from the iQ-R reference manual MELSEC iQ-R CPU User's Manual (sh082487h), section "デバイス点数の使用範囲" (P.410). The library uses the maximum configurable values (i.e. the upper bound of what GX Works3 will let you set), assuming the largest CPU model with extended SRAM cassette.

Category Examples
Bit devices X0..X2FFF, M0..M161882111, B0..B9A61FFF, L0..L32767, S0..S16383
Direct I/O DX0..DX2FFF, DY0..DY2FFF (same hex range as X/Y)
Word devices D0..D10117631, W0..W9A61FF, R0..R32767, RD0..RD1048575
System SM0..SM4095, SD0..SD4095, FX0..FXF, FY0..FYF, FD0..FD4
SFC BL0..BL319 (block), TR0..TR16383 (transition), BL<n>\S0..S511 (in-block step)
Index Z0..Z23, LZ0..LZ11
Pointer/Nest P0..P32767, I0..I1023, N0..N14
Safety SA\X0..SA\X2FFF, SA\M0..SA\M638975, SA\D0..SA\D39935, ...

Modifier compatibility

The validator enforces the modifier-applicability matrix from the iQ-R Programming Manual (CPU Instructions / FUN/FB) §1.2 and the Application Manual §35.1 / §39.1.

Modifier Example Allowed on
Bit spec .X D100.A Word devices: D, W, SW, FD, SD, R, ZR, RD, U\G, U3E\G, J\W, J\SW
Digit spec K<n> K4M0 Bit devices: X, Y, M, L, B, F, SB, V, S, FX, FY, SM
Indirect @ @D0 T, ST, C, D, W, SW, FD, SD, R, ZR, RD, U\G, J\W, J\SW, U3E\G
Local # #D0 M, V, T, ST, C, LC, LT, LST, D, Z, LZ
Index Z D0Z2 Most word/bit devices (not FX, FY, N, Z itself)
Index LZ / ZZ D0LZ0 / D0Z0Z1 M, B, SB, T, ST, LT, LST, C, LC, D, W, SW, R, ZR, RD
Safety SA\ SA\D100 X, Y, M, B, T, ST, C, D, W, SM, SD

Combinational rules

  • The prefix order is fixed: [@] [SA\] [K<n>] [#] <base> — out-of-order combinations are rejected.
  • @ with bit-spec is allowed (e.g. @D100.A) because indirect dereferences to a word.
  • Bit-spec and digit-spec cannot both appear on one operand.
  • ZZ notation requires consecutive registers: Z3Z4 OK, Z3Z2 and Z3Z5 rejected.
  • Safety devices forbid @ and index modification (per Application Manual §39.1).
  • The continuity check rejects K<n><dev><base> where base + n*4 - 1 > max_no.

Constants

Type Examples Range
Boolean TRUE, FALSE
Decimal K123, +123, -123, 12_3 -2,147,483,648 .. 4,294,967,295
Hex HFF, H1234, 16#FF H0 .. HFFFFFFFF
Binary 2#0110_1010 (within the integer range)
Octal 8#377 (within the integer range)
Real E1.234, 1.0E6, E1.001-6 IEEE 754 double; flags single-precision fit
String 'ABC', 'A$LB', '$41$42' up to 255 bytes (CP932)
WString "ABC", "$22quoted$22" up to 255 Unicode characters
Time T#1d2h3m4s5ms, TIME#-31m23s -24d20h31m23s648ms .. 24d20h31m23s647ms

String escape sequences

Inside a string literal, $ is the escape character (per iQ-R Application Manual §26.5):

Sequence Meaning
$$ literal $
$' literal ' (use inside single-quoted strings)
$" literal " (use inside double-quoted strings)
$L / $l line feed (LF, 0x0A)
$N / $n new line (LF, 0x0A)
$P / $p form feed / page break (0x0C)
$R / $r carriage return (0x0D)
$T / $t horizontal tab (0x09)
$<HH> the ASCII character with hex code HH (must be ≤ 0x7F)

The validator decodes escape sequences in result.value (e.g. 'A$LB' produces value = "A\nB") and rejects malformed escapes such as '$X', '$1G', '$80' (out of ASCII range), or a trailing lone $.


Devices and constructs that are NOT supported

The following are intentionally outside the scope of this validator. Strings using these forms will either be rejected, parsed differently than GX Works3 would, or accepted only because their textual form happens to overlap with a supported construct.

Devices

Construct Example Reason
MELSEC-Q legacy devices Q\X0 Q-series compatibility prefixes are not common in iQ-R native programs
Network No.0 link direct J0\W0 The iQ-R spec defines J1..J239 only
Custom user devices via DEVICE_SPECS extension MyDev0 The validator uses a fixed device table; new device kinds require code changes

Labels

Construct Example Reason
Global / local labels bMyFlag, gCounter Label resolution requires the project's GX Works3 label table; this validator works on raw device strings only
Unit labels RX1.bModuleReady, Q01\stEvent Generated by GX Works3 from each unit's FB reference; out of scope
Structure / array members stMotor.iSpeed, arrPos[5], arrPos[5,2] Requires user-defined type information
System labels iQ Works system label name iQ Works integration data is not parsed

Constants and operands

Construct Example Reason
Constant range matching to instruction operand types MOV K70000 D0 Whether K70000 fits a 16-bit signed operand depends on the instruction (MOV vs DMOV); this validator only checks the broadest 32-bit range
Per-CPU model device counts R04CPU has different defaults than R120CPU The validator uses the maximum configurable range across all CPU models. A device accepted here may not fit a small CPU's actual allocation

Project-aware constraints

The validator is stateless — it does not read CPU parameters or label tables. The following checks would require project-aware logic and are NOT performed:

  • User-allocated device range — whether the device fits within the project's actual デバイス点数 setting (rather than the maximum configurable count). For example, a project might allocate only 8K points to M, so M10000 would be invalid in that project even though we accept M0..M161882111.
  • File register file selectionZR upper bound depends on which .QDR file is loaded and the extended SRAM cassette size.
  • Network No. existenceJ239\W0 is syntactically valid but only meaningful if network 239 is actually configured.
  • Unit number existenceU7F\G100 is syntactically valid but only meaningful if a unit is mounted at I/O 7F0..7FF.
  • Safety CPU vs. general CPU — Safety device strings (SA\...) are accepted regardless of whether the target is actually a safety CPU model.
  • Read-only / write-only operand correctness — e.g. OUT X0 would compile-error in GX Works3 because X is read-only, but this validator only checks that X0 is a valid device reference.

If your use case needs any of these, treat this validator as a fast first-pass screen and combine it with project-aware checks driven by the actual .gx3 project data.


Limitations

  • The ZR upper bound is set to 0x7FFFFF (assuming a 16 MB extended SRAM cassette). If your project uses a smaller file-register allocation, you can override it:

    from iqr_device_validator import DEVICE_SPECS, DeviceSpec
    DEVICE_SPECS["ZR"] = DeviceSpec(radix=10, max_no=131071, ...)  # for 256KB
    
  • For real constants near the boundary, the fits_single flag in the result indicates whether the value is representable in single-precision. The library always accepts the value if it fits in double-precision, since the actual instruction width determines which is required.

  • The SFC transition device TR<n> is accepted syntactically, but per the iQ-R reference manual it is only usable as a device comment, not as an instruction operand. The validator does not enforce the comment-only restriction since that requires knowing the surrounding instruction context.

  • The default SFC block range (BL0..BL319) reflects the maximum for R04CPU and above. R00/R01/R02CPU support only BL0..BL127; if you target those models, override DEVICE_SPECS["BL"].max_no = 127.


Running tests

git clone https://github.com/mokouliszt/iqr_device_validator.git
cd iqr_device_validator
python -m pytest

The test suite includes 88+ cases covering every device kind, modifier combination, range boundary, and constant type.


References

The behaviour is grounded in the following Mitsubishi reference manuals:

  • MELSEC iQ-R CPU ユニット ユーザーズマニュアル (sh082487h) — general device list and configurable ranges (§27.1, §27.2)
  • MELSEC iQ-R CPU ユニット ユーザーズマニュアル (応用編) — safety devices (§35.1, §39.1), constants (§26, §31)
  • MELSEC iQ-R プログラミングマニュアル (CPUユニット用命令/汎用FUN/汎用FB編) — bit/digit specification syntax, indirect (@), index modification

This library is not affiliated with or endorsed by Mitsubishi Electric. MELSEC, iQ-R, and GX Works3 are trademarks of Mitsubishi Electric Corporation.


License

MIT License. See LICENSE for details.


Contributing

Bug reports and pull requests are welcome on GitHub. If you find a device range that disagrees with your project's setup, please file an issue with:

  1. The exact device string that was rejected (or accepted incorrectly)
  2. The CPU model and extended SRAM cassette in your project
  3. The expected behaviour with a manual reference if possible

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iqr_device_validator-0.1.0.tar.gz (25.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iqr_device_validator-0.1.0-py3-none-any.whl (18.3 kB view details)

Uploaded Python 3

File details

Details for the file iqr_device_validator-0.1.0.tar.gz.

File metadata

  • Download URL: iqr_device_validator-0.1.0.tar.gz
  • Upload date:
  • Size: 25.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for iqr_device_validator-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f982b98009c570d683b0118eb15851c6c73982c72b7ae847220b7ece0e72c1d0
MD5 55077d2077b5fc22a9ea705a85dfd233
BLAKE2b-256 304dccd1b6f6e9fd9866d7e82aaead2047435b14e382ac41eb8b3ac58495cf70

See more details on using hashes here.

File details

Details for the file iqr_device_validator-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for iqr_device_validator-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a38383e2e01b37546c0d8adef87649dc47886be78bab9c913ad179d751932c4
MD5 e8d5eae0113a91efd15bc9e874ed8bae
BLAKE2b-256 13d1ca09c0fc37383e9a2c138ce3d4fc42117484a60d7e3ac5cd4b72ad2557dd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page