sphinx-contrib / matlabdomain

A Sphinx extension for documenting Matlab code
http://sphinxcontrib-matlabdomain.readthedocs.io/
Other
70 stars 45 forks source link

Parser fails while parsing new syntax extensions for the class properties #57

Closed Ganimed closed 6 years ago

Ganimed commented 6 years ago

Dear all,

In the last 3 Years Mathworks made a lot of changes and extensions for the Matlab-language, i.e. in OO-programming.

Currently I'm documenting my Matlab-Library for my thesis. In this library I needed to use very often the new (undocumented) syntax extensions to enforce the property types for the class property names. These new extensions are very helpful and makes the verification very easy if a property has the correct type. See following discussions below:

In general, the new syntax for the class properties is defined as follows:

properties
   propName@className dimensionType = initialValue;
end

For the dimensionType there are three possible options, matrix, vector or scalar.

I have made a very simple test class which has only properties. For example this simple class works in Sphinx with your latest matlabdomain very well:

classdef MyTestDataType
    % MYTESTDATATYPE is a data type (class) for specific links.
    %
    % Args:
    %   link_name (string):    Name of the reference link.
    %   pos (double, vector):  Cartesian position of the link.
    %   rotm (double, matrix): (3 x 3) rotation matrix.
    %   idx (uint8, scalar):   Index of the reference link.
    properties
        link_name = 'none';
        pos       = zeros(3,1);
        rotm      = eye(3,3);
        idx       = 0;
    end
end

But when I replace the above properties with

link_name@char     = 'none';
pos@double  vector = zeros(3,1);
rotm@double matrix = zeros(3,3);
idx@uint8   scalar = 0;

Then I will get following error from your parser:

Exception occurred:
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 746, in __init__
    raise TypeError('Expected property.')
TypeError: Expected property.

Here is the full log:

# Sphinx version: 1.6.6
# Python version: 2.7.12 (CPython)
# Docutils version: 0.14 
# Jinja2 version: 2.10
# Last messages:
#   Running Sphinx v1.6.6
#   making output directory...
#   loading pickled environment...
#   not yet created
#   building [mo]: targets for 0 po files that are out of date
#   building [html]: targets for 4 source files that are out of date
#   updating environment:
#   4 added, 0 changed, 0 removed
#   reading sources... [ 25%] _sources/documentation
#   reading sources... [ 50%] _sources/wbm/modules
# Loaded extensions:
#   sphinx.ext.mathjax (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/mathjax.pyc
#   sphinx.ext.viewcode (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/viewcode.pyc
#   sphinx.ext.napoleon (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/napoleon/__init__.pyc
#   sphinx.ext.autodoc (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/autodoc.pyc
#   sphinxcontrib.matlab (unknown version) from /usr/local/lib/python2.7/dist-packages/sphinxcontrib/matlab.pyc
#   sphinx.ext.graphviz (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/graphviz.pyc
#   alabaster (0.7.10) from /usr/local/lib/python2.7/dist-packages/alabaster/__init__.pyc
#   sphinx.ext.ifconfig (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/ifconfig.pyc
#   sphinx.ext.githubpages (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/githubpages.pyc
#   sphinxcontrib.plantuml (unknown version) from /usr/local/lib/python2.7/dist-packages/sphinxcontrib/plantuml.pyc
#   sphinx.ext.autosummary (1.6.6) from /usr/local/lib/python2.7/dist-packages/sphinx/ext/autosummary/__init__.pyc
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/sphinx/cmdline.py", line 306, in main
    app.build(opts.force_all, filenames)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/application.py", line 339, in build
    self.builder.build_update()
  File "/usr/local/lib/python2.7/dist-packages/sphinx/builders/__init__.py", line 329, in build_update
    'out of date' % len(to_build))
  File "/usr/local/lib/python2.7/dist-packages/sphinx/builders/__init__.py", line 342, in build
    updated_docnames = set(self.env.update(self.config, self.srcdir, self.doctreedir))
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 601, in update
    self._read_serial(docnames, self.app)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 621, in _read_serial
    self.read_doc(docname, app)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/environment/__init__.py", line 758, in read_doc
    pub.publish()
  File "/usr/local/lib/python2.7/dist-packages/docutils/core.py", line 217, in publish
    self.settings)
  File "/usr/local/lib/python2.7/dist-packages/sphinx/io.py", line 74, in read
    self.parse()
  File "/usr/local/lib/python2.7/dist-packages/docutils/readers/__init__.py", line 78, in parse
    self.parser.parse(self.input, document)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/__init__.py", line 191, in parse
    self.statemachine.run(inputlines, document, inliner=self.inliner)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 171, in run
    input_source=document['source'])
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2753, in underline
    self.section(title, source, style, lineno - 1, messages)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 327, in section
    self.new_subsection(title, lineno, messages)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 395, in new_subsection
    node=section_node, match_titles=True)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 282, in nested_parse
    node=node, match_titles=match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2328, in explicit_markup
    self.explicit_list(blank_finish)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2358, in explicit_list
    match_titles=self.state_machine.match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 319, in nested_list_parse
    node=node, match_titles=match_titles)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 196, in run
    results = StateMachineWS.run(self, input_lines, input_offset)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 239, in run
    context, state, transitions)
  File "/usr/local/lib/python2.7/dist-packages/docutils/statemachine.py", line 460, in check_line
    return method(match, context, next_state)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2631, in explicit_markup
    nodelist, blank_finish = self.explicit_construct(match)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2338, in explicit_construct
    return method(self, expmatch)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2081, in directive
    directive_class, match, type_name, option_presets)
  File "/usr/local/lib/python2.7/dist-packages/docutils/parsers/rst/states.py", line 2130, in run_directive
    result = directive_instance.run()
  File "/usr/local/lib/python2.7/dist-packages/sphinx/ext/autodoc.py", line 1843, in run
    documenter.generate(more_content=self.content)
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_documenters.py", line 419, in generate
    self.analyzer.find_attr_docs()
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 1141, in find_attr_docs
    for k, v in mod.safe_getmembers():
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 231, in safe_getmembers
    value = self.getter(key, None)
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 285, in getter
    attr = MatObject.matlabify('.'.join([self.package, name]))
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 133, in matlabify
    return MatObject.parse_mfile(mfile, name, path)  # parse mfile
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 186, in parse_mfile
    return MatClass(name, modname, tks)
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 746, in __init__
    raise TypeError('Expected property.')
TypeError: Expected property.

Sphinx is with its plugins one of the best documentation tools, but unfortunately all current parser for documenting code in Matlab doesn't support this new syntax.

Is it possible to extend the parser with this new syntax s.t. Sphinx can interpret the new property syntax like below (in Google style with Napoleon)?

% Args:
%   link_name (char):      Name of the reference link.
%   pos (double, vector):  Cartesian position of the link.
%   rotm (double, matrix): (3 x 3) rotation matrix.
%   idx (uint8, scalar):   Index of the reference link.

Or optional, which should be easier, is it possible that the new syntax right beside the property name will be ignored by the parser?

By the way, I have to set also a comment header into each file (copyright, license, etc.), like in C/C++:

% This is an Comment Header % Copyright (C) 2018, by John Doe. % % some descriptions ... % % lisence (GPL, BSD, etc.) %%

How is it possible, or how can I force, that the parser of the matlabdomain will ignore this comment header without raising any errors?

Thank you very much in advance!

With best regards, Ganimed.

joeced commented 6 years ago

Just a few comments. In https://se.mathworks.com/help/matlab/matlab_oop/defining-properties.html and https://se.mathworks.com/help/matlab/matlab_oop/validate-property-values.html the notation for types on properties is a bit different than what you showed, but the end result is the same error.

classdef PropertiesWithType
    % PROPERTIESWITHTYPE is a data type (class) for specific links.
    %
    % Args:
    %   link_name (string):    Name of the reference link.
    %   pos (double, vector):  Cartesian position of the link.
    %   rotm (double, matrix): (3 x 3) rotation matrix.
    %   idx (uint8, scalar):   Index of the reference link.
    properties
        link_name string = 'none';
        pos(3, 1) double = zeros(3,1);
        rotm(3,3) double = eye(3,3);
        idx uint8       = 0;
    end
end

Regarding the comment header, just keep a empty line between the docstring and the header like

function a = rot(b)
% Some docstring

%* Copyright header
% ...
%*
Ganimed commented 6 years ago

Thank's for the fast response. I have checked your links above. Your example is a newer variant of setting types for properties. I have found out, that the undocumented syntax that I use, is an older and stricter variant of the newer version which was officially introduced in Matlab R2016a. So the newer variant is quite young. I guess, there are still some variants under development.

Thank's for the information about the comment header. Now I know how to do it. But there is no possibility to put it outside of a class or single function, i.e. when the class/function is very small and the comment header is quite large?

By the way, this link is also quite interesting: https://undocumentedmatlab.com/blog/setting-class-property-types-2

joeced commented 6 years ago

Thanks for the link.

You are right about the new syntax being introduced in Matlab 2016a, and as far I can tell the size restrictions are first documented in Matlab 2017a (https://se.mathworks.com/help/releases/R2017a/matlab/matlab_oop/validate-property-values.html).

I'm mostly for only supporting the official syntax, but the first task is to figure out how to support property types. I'm still not sure what will be best. I could start out with not throwing an error :)

Ganimed commented 6 years ago

I fully agree with you, but I have read in setting-class-property-types-2, that the older syntax is backward compatible until R2010a and quite a lot of professional Matlab-programmer using it, whereas the newer (official) syntax is only supported from R2016a/R2017a and newer. Furthermore nobody knows how long the older syntax will be supported by Matlab or if it will be officially introduced later. I have also the feeling, that in the next releases (≥ R2018a) new changes will be come out stepwisely.

I would suggest, if somebody is using the old syntax beginning with the "@" symbol after the variable name, that the parser is cutting out this section of the line and sticking the rest ("=" symbol with default value or a comment/docstring) together. I.e. the parser will ignore this part.

For the newer syntax, an own sub-function for parsing should be helpful. Maybe with the help of regular expression you can parse the round brackets "( )" for the dimensions and the corresponding type. The function-part with the curly brackets "{ }", I would cut it out (there are too many special function names to be cared) or, add it to the comment line as it is.

For example the following code line, Label(1,:) char {mustBeMember(Label,{'High','Medium','Low'})} = 'Low'; % This is a special label., will be converted to "Label (char, vector) - This is a special label. Restricted to: mustBeMember(Label,{'High', 'Medium', 'Low'})".

Moreover, the dimensions of the properties could be interpreted by the parser as,

At the moment I can make only some suggestions, I have not the time to help in coding (maybe later).

In accordance to the comment header, I have to set the header on the top of the file. Maybe I will add this part by myself to the parser (when I have time). But this is not urgent now.

joeced commented 6 years ago

Thanks for the suggestions.

I cannot recommend comment header in the top of the file, sphinxcontrib-matlabdomain will ignore the file.

mikofski commented 6 years ago

Sorry, I should have chimed in here. The ethic of the MATLAB domain is to use the Pygments MATLAB lexer to parse the code. Therefore, if there is an issue with interpretation of the MATLAB code, then this should be pushed up to Pygments, not posted here. Of course the MATLAB lexicon is changing every year. It should not be Sphinx's job to keep up with a languages lexicon, other than to know how to format it for publishing the API. Does that help clarify anything? If not, of course, you can ignore me.

Do you know what tokens Pygments is returning for these new properties blocks?

joeced commented 6 years ago

Using this class as input

classdef PropTypeOld
    properties
        link_name@char = 'none';
        pos@double vector = zeros(3,1);
        rotm@double matrix = zeros(3,3);
        idx@uint8 scalar = 0;
    end
end

Produces this list of tokens from Pygments

[(Token.Keyword, 'classdef'),
 (Token.Text, ' '),
 (Token.Name, 'PropTypeOld'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'properties'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'link_name'),
 (Token.Punctuation, '@'),
 (Token.Name, 'char'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "none'"),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'pos'),
 (Token.Punctuation, '@'),
 (Token.Name, 'double'),
 (Token.Text, ' '),
 (Token.Name, 'vector'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Name.Builtin, 'zeros'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ')'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'rotm'),
 (Token.Punctuation, '@'),
 (Token.Name, 'double'),
 (Token.Text, ' '),
 (Token.Name, 'matrix'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Name.Builtin, 'zeros'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ')'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'idx'),
 (Token.Punctuation, '@'),
 (Token.Name, 'uint8'),
 (Token.Text, ' '),
 (Token.Name, 'scalar'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Literal.Number.Integer, '0'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'end'),
 (Token.Text, '\n'),
 (Token.Keyword, 'end'),
 (Token.Text, '\n')]

Given a new style class

classdef PropTypeNew
    properties
        link_name string = 'none';
        pos(3,1) double = zeros(3,1);
        rotm(3,3) double = eye(3,3);
        idx uint8 = 0;
    end
end

Produces this list of tokens

[(Token.Keyword, 'classdef'),
 (Token.Text, ' '),
 (Token.Name, 'PropTypeNew'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'properties'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'link_name'),
 (Token.Text, ' '),
 (Token.Name, 'string'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "none'"),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'pos'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ')'),
 (Token.Text, ' '),
 (Token.Name, 'double'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Name.Builtin, 'zeros'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ')'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'rotm'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ')'),
 (Token.Text, ' '),
 (Token.Name, 'double'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Name.Builtin, 'eye'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ')'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'idx'),
 (Token.Text, ' '),
 (Token.Name, 'uint8'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Literal.Number.Integer, '0'),
 (Token.Punctuation, ';'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'end'),
 (Token.Text, '\n'),
 (Token.Keyword, 'end'),
 (Token.Text, '\n')]

So it look OK to me. A property with type, can be a series of ((Token.Name, '...'),[Token.Text or Token.Punctuation],[(Token.Name, '...')).

Ganimed commented 6 years ago

So the Matlab-Lexer from Pygments is parsing both variants, the old and the new syntax, correctly (or it seems to be). But then is the question what is causing the exception?

@joeced: I have tried out (just for fun) if the sphinxcontrib-matlabdomain will really ignore a file, if inside is a comment header or any comment at first. And I must say it does not, the parser will crash for functions and classes (scripts are not tested yet):

Exception occurred:
  File "/usr/local/lib/python2.7/dist-packages/sphinxcontrib/mat_types.py", line 1104, in for_module
    obj = cls.for_folder(mod.path, modname)
AttributeError: 'module' object has no attribute 'path'

In this case I would open a second issue. Furthermore I have made already a solution for it. Sorry that I'm producing some work.

joeced commented 6 years ago

Just for reference i tried an example from https://se.mathworks.com/help/matlab/matlab_oop/validate-property-values.html

classdef ValidateProps
   properties
      Location(1,3) double {mustBeReal, mustBeFinite}
      Label(1,:) char {mustBeMember(Label,{'High','Medium','Low'})} = 'Low'
      State(1,1) matlab.lang.OnOffSwitchState
   end
end

Which produces this list of tokens

[(Token.Keyword, 'classdef'),
 (Token.Text, ' '),
 (Token.Name, 'ValidateProps'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'properties'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'Location'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '3'),
 (Token.Punctuation, ')'),
 (Token.Text, ' '),
 (Token.Name, 'double'),
 (Token.Text, ' '),
 (Token.Punctuation, '{'),
 (Token.Name, 'mustBeReal'),
 (Token.Punctuation, ','),
 (Token.Text, ' '),
 (Token.Name, 'mustBeFinite'),
 (Token.Punctuation, '}'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'Label'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ','),
 (Token.Punctuation, ':'),
 (Token.Punctuation, ')'),
 (Token.Text, ' '),
 (Token.Name, 'char'),
 (Token.Text, ' '),
 (Token.Punctuation, '{'),
 (Token.Name, 'mustBeMember'),
 (Token.Punctuation, '('),
 (Token.Name, 'Label'),
 (Token.Punctuation, ','),
 (Token.Punctuation, '{'),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "High'"),
 (Token.Punctuation, ','),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "Medium'"),
 (Token.Punctuation, ','),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "Low'"),
 (Token.Punctuation, '}'),
 (Token.Punctuation, ')'),
 (Token.Punctuation, '}'),
 (Token.Text, ' '),
 (Token.Punctuation, '='),
 (Token.Text, ' '),
 (Token.Literal.String, "'"),
 (Token.Literal.String, "Low'"),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Name, 'State'),
 (Token.Punctuation, '('),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ','),
 (Token.Literal.Number.Integer, '1'),
 (Token.Punctuation, ')'),
 (Token.Text, ' '),
 (Token.Name, 'matlab'),
 (Token.Punctuation, '.'),
 (Token.Name, 'lang'),
 (Token.Punctuation, '.'),
 (Token.Name, 'OnOffSwitchState'),
 (Token.Text, '\n'),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Text, ' '),
 (Token.Keyword, 'end'),
 (Token.Text, '\n'),
 (Token.Keyword, 'end'),
 (Token.Text, '\n')]

Firstly, I'll work on sphinxcontrib-matlabdomain, not crashing while parsing property types/classes. The key thing that separates the properties are (Token.Text, '\n'). I'm doing this in the property_types branch.

Ganimed commented 6 years ago

That's a good idea for the begin. In the next days I will check your property_types branch. Maybe I can help.