Commit c1bc8679 authored by Fabrice Salvaire's avatar Fabrice Salvaire

cleanup

parent 693afdae
......@@ -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__ = '*'
......
......@@ -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.
......
......@@ -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 <https://www.dabeaz.com/ply/ply.html>`_ which implement a LALR(1) parser similar to the
tools **lex** and **yacc**.
The parser construct an `abstract syntax tree (AST)
<https://en.wikipedia.org/wiki/Abstract_syntax_tree>`_ 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
<https://www.nist.gov/publications/nist-rs274ngc-interpreter-version-3>`_
* 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
......@@ -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
<https://www.nist.gov/publications/nist-rs274ngc-interpreter-version-3>`_
* The documentation of the `Linux CNC <http://linuxcnc.org>`_ project, formerly Enhanced Machine
Controller developed at NIST,
* EIA Standard RS-274-D Interchangeable Variable Block Data Format for Positioning, Contouring, and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment