226 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
			
		
		
	
	
			226 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			YAML
		
	
	
	
	
	
%YAML 1.2
 | 
						|
---
 | 
						|
#
 | 
						|
# G-Code (RepRap, not ISO-6983)
 | 
						|
# Author: @thinkyhead
 | 
						|
#
 | 
						|
# RapRap G-Code is very simple.
 | 
						|
#
 | 
						|
# TODO: Lines that start with N get a different context, accepting a checksum.
 | 
						|
#
 | 
						|
name: G-Code (RepRap)
 | 
						|
file_extensions:
 | 
						|
  - [ g, gco, gcode ]
 | 
						|
scope: source.gcode
 | 
						|
variables:
 | 
						|
  decimal: '[+-]?\d+(\.\d*)?'
 | 
						|
 | 
						|
contexts:
 | 
						|
  prototype:
 | 
						|
    - match: \s+
 | 
						|
 | 
						|
    - include: mixin_comment
 | 
						|
 | 
						|
    - match: $
 | 
						|
      pop: true
 | 
						|
 | 
						|
  main:
 | 
						|
    - meta_scope: line.gcode
 | 
						|
 | 
						|
    - match: '([Nn]\s*(\d+))'
 | 
						|
      captures:
 | 
						|
        1: entity.nword.gcode
 | 
						|
        2: constant.numeric.line-number.gcode
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: gcode_command
 | 
						|
 | 
						|
  # G, M, or T command
 | 
						|
  gcode_command:
 | 
						|
    - meta_content_scope: ctx.command.gcode
 | 
						|
 | 
						|
    # M20 S2 P/path/to/file/name.gco
 | 
						|
    - match: ([Mm](20))\s*((S)(2)\s*(P))
 | 
						|
      captures:
 | 
						|
        1: entity.command.gcode markup.bold.gcode
 | 
						|
        2: constant.numeric.command.gcode
 | 
						|
        3: ctx.params.gcode
 | 
						|
        4: keyword.param.gcode
 | 
						|
        5: constant.numeric.param.gcode
 | 
						|
        6: keyword.param.gcode
 | 
						|
      set: gcode_string_arg
 | 
						|
 | 
						|
    # M117 or M118 - Commands taking a string
 | 
						|
    - match: ([Mm]\s*(11[78]))\b
 | 
						|
      captures:
 | 
						|
        1: entity.command.gcode markup.bold.gcode
 | 
						|
        2: constant.numeric.command.gcode
 | 
						|
      set: gcode_string_arg
 | 
						|
 | 
						|
    # Other commands, followed by data
 | 
						|
    - match: ([GMTgmt]\s*(\d+)((\.)(\d+))?)
 | 
						|
      captures:
 | 
						|
        1: entity.command.gcode markup.bold.gcode
 | 
						|
        2: constant.numeric.command.gcode
 | 
						|
        4: entity.separator.subcode
 | 
						|
        5: constant.numeric.subcode
 | 
						|
      set: gcode_params
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: syntax_error
 | 
						|
 | 
						|
  # Parameters of a command
 | 
						|
  gcode_params:
 | 
						|
    - meta_content_scope: ctx.params.gcode
 | 
						|
 | 
						|
    # M32 [S<pos>] [P<bool>] !/path/file.gco#
 | 
						|
    - match: \!
 | 
						|
      scope: punctuation.string.path.open.gcode
 | 
						|
      push: gcode_path_arg
 | 
						|
 | 
						|
    # asterisk starts a checksum
 | 
						|
    - match: \*
 | 
						|
      scope: punctuation.marker.checksum.gcode
 | 
						|
      set: gcode_checksum
 | 
						|
 | 
						|
    # parameter and single-quoted value
 | 
						|
    - match: ([A-Za-z])\s*(')
 | 
						|
      captures:
 | 
						|
        1: keyword.param.gcode
 | 
						|
        2: punctuation.quote.single.open.gcode
 | 
						|
      push: gcode_string_arg_quoted_single
 | 
						|
 | 
						|
    # parameter and double-quoted value
 | 
						|
    - match: ([A-Za-z])\s*(")
 | 
						|
      captures:
 | 
						|
        1: keyword.param.gcode
 | 
						|
        2: punctuation.quote.double.open.gcode
 | 
						|
      push: gcode_string_arg_quoted_double
 | 
						|
 | 
						|
    # parameter and list of values
 | 
						|
    - match: ([Ee])\s*(({{decimal}}\s*:\s*)+{{decimal}})
 | 
						|
      captures:
 | 
						|
        1: keyword.param.gcode
 | 
						|
        2: constant.numeric.param.gcode
 | 
						|
 | 
						|
    # parameter and numeric value
 | 
						|
    - match: ([A-Za-z])\s*({{decimal}})
 | 
						|
      captures:
 | 
						|
        1: keyword.param.gcode
 | 
						|
        2: constant.numeric.param.gcode
 | 
						|
 | 
						|
    # parameter with no value
 | 
						|
    - match: '[A-Za-z]'
 | 
						|
      scope: keyword.param.gcode
 | 
						|
      set: gcode_params
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: syntax_error
 | 
						|
 | 
						|
  gcode_string_arg_quoted_single:
 | 
						|
    - meta_content_scope: string.quoted.single.gcode
 | 
						|
 | 
						|
    - match: ([^'\\]+)
 | 
						|
 | 
						|
    - match: (\\)
 | 
						|
      scope: punctuation.string.escape.gcode
 | 
						|
      push: escape_char
 | 
						|
 | 
						|
    - match: (')
 | 
						|
      scope: punctuation.quote.single.close.gcode
 | 
						|
      pop: true
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: syntax_error
 | 
						|
 | 
						|
  gcode_string_arg_quoted_double:
 | 
						|
    - meta_content_scope: string.quoted.double.gcode
 | 
						|
 | 
						|
    - match: ([^"\\]+)
 | 
						|
 | 
						|
    - match: (\\)
 | 
						|
      scope: punctuation.string.escape.gcode
 | 
						|
      push: escape_char
 | 
						|
 | 
						|
    - match: (")
 | 
						|
      scope: punctuation.quote.double.close.gcode
 | 
						|
      pop: true
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: syntax_error
 | 
						|
 | 
						|
  gcode_string_arg:
 | 
						|
    - meta_content_scope: ctx.string.gcode
 | 
						|
 | 
						|
    - match: ([^;]+)
 | 
						|
      scope: string.unquoted.gcode
 | 
						|
 | 
						|
  escape_char:
 | 
						|
    - meta_scope: string.escape.gcode punctuation.string.escape.gcode
 | 
						|
 | 
						|
    - match: '.'
 | 
						|
      pop: true
 | 
						|
 | 
						|
  gcode_path_arg:
 | 
						|
    - meta_content_scope: string.unquoted.path.gcode
 | 
						|
 | 
						|
    - match: (#)
 | 
						|
      scope: punctuation.string.path.close.gcode
 | 
						|
      pop: true
 | 
						|
 | 
						|
  gcode_checksum:
 | 
						|
    - meta_content_scope: constant.numeric.checksum.gcode
 | 
						|
    - meta_include_prototype: false
 | 
						|
 | 
						|
    - match: \d+
 | 
						|
 | 
						|
    - match: ( *)$
 | 
						|
      pop: true
 | 
						|
 | 
						|
    - include: mixin_comment
 | 
						|
 | 
						|
    - match: ()
 | 
						|
      set: syntax_error
 | 
						|
 | 
						|
  # Done interpreting to the end of the line
 | 
						|
  gcode_line_done:
 | 
						|
    - match: \s*$
 | 
						|
      pop: true
 | 
						|
 | 
						|
  # Comments begin with a ';' and finish at the end of the line.
 | 
						|
  mixin_comment:
 | 
						|
    - match: ^\s*;
 | 
						|
      scope: punctuation.comment.line.start
 | 
						|
      set: gcode_comment
 | 
						|
    - match: \s*;
 | 
						|
      scope: punctuation.comment.eol.start
 | 
						|
      set: gcode_comment
 | 
						|
    - match: \s*\(
 | 
						|
      scope: punctuation.paren.comment.open
 | 
						|
      push: gcode_comment_paren
 | 
						|
 | 
						|
  # Comment to end of line.
 | 
						|
  gcode_comment:
 | 
						|
    - meta_content_scope: comment.gcode
 | 
						|
    - match: \s*$
 | 
						|
      pop: true
 | 
						|
 | 
						|
  gcode_comment_paren:
 | 
						|
    - meta_content_scope: paren.comment.gcode
 | 
						|
 | 
						|
    - match: '[^)]+'
 | 
						|
 | 
						|
    - match: '[)]'
 | 
						|
      scope: punctuation.paren.comment.close
 | 
						|
      pop: true
 | 
						|
 | 
						|
    - match: \s*$
 | 
						|
      pop: true
 | 
						|
 | 
						|
  # Everything after this point is broken by a syntax error
 | 
						|
  syntax_error:
 | 
						|
    - meta_scope: invalid.error.syntax.gcode
 | 
						|
 | 
						|
    - match: .*$
 | 
						|
      pop: true
 |