diff --git a/PythonicGcodeMachine/Gcode/Rs274/Ast.py b/PythonicGcodeMachine/Gcode/Rs274/Ast.py index c974f3157006e8ef1405054d1c1cdef55b516bc6..bfd7733097e2103fb765dc65c510ea4630513d3f 100644 --- a/PythonicGcodeMachine/Gcode/Rs274/Ast.py +++ b/PythonicGcodeMachine/Gcode/Rs274/Ast.py @@ -53,7 +53,7 @@ __all__ = [ 'Power', 'DividedBy', 'Modulo', - 'Times', + 'Multiply', 'And', 'ExclusiveOr', 'Subtraction', @@ -77,6 +77,11 @@ class Program: program = Program() program += line + + # Array interface + for line in programs: + print(line) + str(program) """ @@ -142,14 +147,36 @@ class Line: Usage:: - line = Line(def=False, line_number=1, comment='a comment') + line = Line(deleted=False, line_number=1, comment='a comment') + + line.deleted = True + print(line.deleted) + # same apply for line_number and comment + + # Is line not deleted ? + bool(line) + + # Push some items + # Note: order doesn't matter, see RS-274 for details line += Word('G', 0) line += Comment('move') line += Word('X', 10) line += Comment('Y value') line += Word('Y', 20) line += ParameterSetting('1', 1.2) + + # using expression + line += Word('Z', Addition(30, Multiply(Parameter(100), Cosine(30)))) + + # Array interface + for item in line: + print(item) + str(line) + print(line.ansi_str()) # use ANSI colors, see Line.ANSI_... attributes + + Expression can be evaluated using :code:`float(obj.value)`, excepted when we must access a parameter + value. """ @@ -280,6 +307,8 @@ class Line: class Comment(LineItem): + """Class to implement comment""" + ############################################## def __init__(self, text): @@ -317,6 +346,8 @@ class Comment(LineItem): class Word(LineItem): + """Class to implement word""" + LETTERS = ( 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', # 'N', @@ -399,6 +430,8 @@ class ParameterMixin: class ParameterSetting(LineItem, ParameterMixin): + """Class to implement parameter setting""" + ############################################## def __init__(self, parameter, value): @@ -430,6 +463,8 @@ class ParameterSetting(LineItem, ParameterMixin): class Parameter(RealValue, ParameterMixin): + """Class to implement parameter""" + ############################################## def __init__(self, parameter): @@ -443,6 +478,11 @@ class Parameter(RealValue, ParameterMixin): def __str__(self): return '#{0._parameter}'.format(self) + ############################################## + + def __float__(self): + raise NotImplementedError + #################################################################################################### class UnaryOperation(RealValue): @@ -594,7 +634,7 @@ class Modulo(BinaryOperation): __function__ = staticmethod(lambda a, b: a % b) __gcode__ = 'mod' -class Times(BinaryOperation): +class Multiply(BinaryOperation): __function__ = staticmethod(lambda a, b: a * b) __gcode__ = '*' diff --git a/PythonicGcodeMachine/Gcode/Rs274/Lexer.py b/PythonicGcodeMachine/Gcode/Rs274/Lexer.py index a161d876d361b7c385d54562afcd757188c3d467..ed9c95aa906c6d270293ba90b40b79def854eb07 100644 --- a/PythonicGcodeMachine/Gcode/Rs274/Lexer.py +++ b/PythonicGcodeMachine/Gcode/Rs274/Lexer.py @@ -40,11 +40,6 @@ class GcodeLexer: """Class to implement a RS-274 G-code lexer. - For references, see - - * The NIST RS274NGC Interpreter — Version 3 — Appendix E. Production Rules for the RS274/NGC Language - * http://linuxcnc.org/docs/2.7/html/gcode/overview.html - """ # List of token names. diff --git a/PythonicGcodeMachine/Gcode/Rs274/Parser.py b/PythonicGcodeMachine/Gcode/Rs274/Parser.py index 7d47cad21485daabdcd86595ce96f097620bdce9..681d1c286dc19351aebacc9393bd8aca6177dfcc 100644 --- a/PythonicGcodeMachine/Gcode/Rs274/Parser.py +++ b/PythonicGcodeMachine/Gcode/Rs274/Parser.py @@ -18,7 +18,39 @@ # #################################################################################################### -__all__ = ['GcodeParserError', 'GcodeParser'] +"""Module to implement a RS-274 G-code parser. + +Usage:: + + parser = GcodeParser() + ast_line = parser.parse(gcode_line) + ast_program = parser.parse_lines(gcode_lines) + +**Implementation** + +The parser is generated automatically from the grammar defined in this class using the generator +`PLY `_ which implement a LALR(1) parser similar to the +tools **lex** and **yacc**. + +The parser construct an `abstract syntax tree (AST) +`_ during the parsing. + +User can subclass this parser to support a derived G-code flavour. + +**For references, see** + +* `The NIST RS274NGC Interpreter — Version 3 — Appendix E. Production Rules for the RS274/NGC Language + `_ +* http://linuxcnc.org/docs/2.7/html/gcode/overview.html + +""" + +__all__ = [ + 'GcodeParserError', + 'GcodeParser', + 'GcodeParserMixin', + 'GcodeGrammarMixin', +] #################################################################################################### @@ -35,16 +67,11 @@ class GcodeParserError(ValueError): #################################################################################################### -class GcodeParser: +class GcodeGrammarMixin: - """Class to implement a RS-274 G-code parser. + """Mixin to implement the grammar. - For references, see - - * The NIST RS274NGC Interpreter — Version 3 — Appendix E. Production Rules for the RS274/NGC Language - * http://linuxcnc.org/docs/2.7/html/gcode/overview.html - - Production Language + **Production Language for RS-274** The symbols in the productions are mostly standard syntax notation. Meanings of the symbols are: @@ -92,14 +119,13 @@ class GcodeParser: """ - __lexer_cls__ = GcodeLexer - # Build the operation map + # Note: sphinx show locals if not _foo __operation_map__ = {} - for cls_name in Ast.__all__: - cls = getattr(Ast, cls_name) - if hasattr(cls, '__gcode__'): - __operation_map__[cls.__gcode__] = cls + for _cls_name in Ast.__all__: + _cls = getattr(Ast, _cls_name) + if hasattr(_cls, '__gcode__'): + __operation_map__[_cls.__gcode__] = _cls ############################################## @@ -304,6 +330,14 @@ class GcodeParser: def p_error(self, p): raise GcodeParserError(p.lexpos) +#################################################################################################### + +class GcodeParserMixin: + + """Mixin to implement a RS-274 G-code parser""" + + __lexer_cls__ = GcodeLexer + ############################################## def __init__(self): @@ -333,7 +367,10 @@ class GcodeParser: def parse(self, line): - """Parse a G-code line""" + """Parse a G-code line. + + Return a :class:`PythonicGcodeMachine.Gcode.Rs274.Ast.Line` instance. + """ line = line.strip() @@ -353,10 +390,18 @@ class GcodeParser: def parse_lines(self, lines): - """Parse a G-code lines""" + """Parse a G-code lines + + Return a :class:`PythonicGcodeMachine.Gcode.Rs274.Ast.Program` instance. + """ program = Ast.Program() for line in lines.split('\n'): program += self.parse(line) return program + +#################################################################################################### + +class GcodeParser(GcodeParserMixin, GcodeGrammarMixin): + pass diff --git a/PythonicGcodeMachine/Gcode/Rs274/__init__.py b/PythonicGcodeMachine/Gcode/Rs274/__init__.py index 256679a9b02005349073a342d876750caf8c644d..1cee3dd52daf442b4234ad880da35b7169c6c166 100644 --- a/PythonicGcodeMachine/Gcode/Rs274/__init__.py +++ b/PythonicGcodeMachine/Gcode/Rs274/__init__.py @@ -20,6 +20,10 @@ """Module to implement the G-code language. +.. Note:: + Text derived from several sources, like NIST RS-274 paper and Linux CNC project. + cf. supra for references. + History ------- @@ -30,8 +34,9 @@ developed by the EIA in the early 1960s, and finally standardised by ISO in Febr The G-code language has several flavours and historical versions. A list of reference documents follows : -* The NIST RS274NGC Interpreter - Version 3, T. Kramer, F. Proctor, E. Messina, National Institute +* `The NIST RS274NGC Interpreter - Version 3, T. Kramer, F. Proctor, E. Messina, National Institute of Standards and Technology, NISTIR 6556, August 17, 2000 + `_ * The documentation of the `Linux CNC `_ project, formerly Enhanced Machine Controller developed at NIST, * EIA Standard RS-274-D Interchangeable Variable Block Data Format for Positioning, Contouring, and