@top Program { Statement* }

Statement {
  Label Mnemonic Operand "," Operand Comment? Newline
  | Mnemonic Operand "," Operand Comment? Newline
  | Label Comment? Newline
  | Comment Newline
  | Label Db Comment? Newline
  | Label Dw Comment? Newline
}

Mnemonic {
  "nop"|"ldc"|"add"|"div"|"and"|"or"|"xor"|"not"|"lsl"|"lsr"|"ld"|"st"|"mov"|"cp"|"jp"|"ltjp"|"gtjp"|"eqjp"|"call"|"ret"
}

Operand {
  Register | Immediate
}

Register {
  "AX" | "BX" | "CX" | "DX" | "EX" | "FX" | "GX"
}

Immediate {
  ImmediateToken
}

Comment {
  CommentToken
}

Label {
  LabelToken
}

Newline {
  NewlineToken
}

Db {
  "db" NumberList
}

Dw {
  "dw" StringList
}

NumberList {
  ImmediateToken ("," ImmediateToken)*
}

StringList {
  StringToken ("," StringToken)*
}

@tokens {
  ImmediateToken { $[0-9]+ }
  CommentToken { ";" $[^\n]* }
  LabelToken { $[a-zA-Z_]$[a-zA-Z0-9_]* ":" }
  StringToken { "'" $[a-zA-Z0-9_]* "'" }
  NewlineToken { "\n" }
}