Where can I find a formal grammar for MATLAB?
Asked Answered
H

5

29

I would like to write a lexer generator to convert a basic subset of the MATLAB language to C#, C++, etc. To help me do this, I would like to find a document containing the formal grammar for MATLAB. Having spent a bit of time investigating this, it seems that Mathworks do not provide one.

Does anyone know where I could find such a document?

Hahnert answered 6/3, 2012 at 12:0 Comment(5)
I strongly suspect that the Mathworks do not define a formal grammar for Matlab. I'll watch for answers to this one.Stingaree
Octave parses the grammar of Matlab. Might be worthwhile checking what they already did.Wrack
The lex file in the Octave source is helpful. I have also found an antl parser which converts matlab to C and Java.Hahnert
Have you seen this ANTLR Grammar?Toratorah
It's not in BNF form, but MathWorks does have a Github repo with a .tmLanguage file for syntax highlighting.Ocd
D
6

Excellent opportunity to write your own formal grammar :)

If you should choose to write the grammer your self, I can recommend BNFC which can take a formal BNF grammar and construct data structures and lexers/parsers for a couple of target languages (C/C++, C#, Java, Haskell etc.). This would save you a lot of time and let you focus on formulating the grammar, and then get right to implementing the converter in your language of preference.

If nothing else, the link to BNFC contains some help and pointers on how to formulate a BNF grammar. Best of luck!

Disrupt answered 6/3, 2012 at 12:7 Comment(2)
Thanks for the advice, I will have a look. I was thinking of using fslex and fsyacc.Hahnert
the link is broken!Toratorah
L
11

This is not complete grammar but yacc-keable for matlab provided for a compiler course in year 2000. From this, you can easily create BNF and EBNF.

primary_expression
        : IDENTIFIER                  
        | CONSTANT    
        | STRING_LITERAL        
        | '(' expression ')'
        | '[' ']'
        | '[' array_list ']'
        ;

postfix_expression
        : primary_expression
        | array_expression
        | postfix_expression TRANSPOSE
        | postfix_expression NCTRANSPOSE
        ;

index_expression
        : ':'
        | expression
        ;

index_expression_list
        : index_expression
        | index_expression_list ',' index_expression
        ;

array_expression
        : IDENTIFIER '(' index_expression_list ')'
        ;

unary_expression
        : postfix_expression
        | unary_operator postfix_expression
        ;

unary_operator
        : '+'
        | '-'
        | '~'
        ;

multiplicative_expression
        : unary_expression
        | multiplicative_expression '*' unary_expression
        | multiplicative_expression '/' unary_expression
        | multiplicative_expression '\\' unary_expression
        | multiplicative_expression '^' unary_expression
        | multiplicative_expression ARRAYMUL unary_expression
        | multiplicative_expression ARRAYDIV unary_expression
        | multiplicative_expression ARRAYRDIV unary_expression
        | multiplicative_expression ARRAYPOW unary_expression
        ;

additive_expression
        : multiplicative_expression
        | additive_expression '+' multiplicative_expression
        | additive_expression '-' multiplicative_expression
        ;

relational_expression
        : additive_expression
        | relational_expression '<' additive_expression
        | relational_expression '>' additive_expression
        | relational_expression LE_OP additive_expression
        | relational_expression GE_OP additive_expression
        ;

equality_expression
        : relational_expression
        | equality_expression EQ_OP relational_expression
        | equality_expression NE_OP relational_expression
        ;

and_expression
        : equality_expression
        | and_expression '&' equality_expression
        ;

or_expression
        : and_expression
        | or_expression '|' and_expression
        ;

expression
        : or_expression
    | expression ':' or_expression
    ;

assignment_expression
        : postfix_expression '=' expression

eostmt
        :  ','
        |  ';'
        |  CR
        ;

statement
        : global_statement
        | clear_statement
        | assignment_statement
        | expression_statement
        | selection_statement
        | iteration_statement
        | jump_statement
        ;

statement_list
        : statement
        | statement_list statement
        ;

identifier_list
        : IDENTIFIER
        | identifier_list IDENTIFIER
        ;

global_statement
        : GLOBAL identifier_list eostmt
        ;

clear_statement
        : CLEAR identifier_list eostmt
        ;

expression_statement
        : eostmt
        | expression eostmt
        ;

assignment_statement
        : assignment_expression eostmt
        ;

array_element
        : expression
        | expression_statement
        ;

array_list
        : array_element
        | array_list array_element
        ;

selection_statement
        : IF expression statement_list END eostmt
        | IF expression statement_list ELSE statement_list END eostmt
        | IF expression statement_list elseif_clause END eostmt
        | IF expression statement_list elseif_clause
          ELSE statement_list END eostmt
        ;

elseif_clause
        : ELSEIF expression statement_list
    | elseif_clause ELSEIF expression statement_list
        ;

iteration_statement
        : WHILE expression statement_list END eostmt
        | FOR IDENTIFIER '=' expression statement_list END eostmt
        | FOR '(' IDENTIFIER '=' expression ')' statement_list END eostmt 
        ;

jump_statement
        : BREAK eostmt
        | RETURN eostmt
        ;

translation_unit
        : statement_list
        | FUNCTION function_declare eostmt statement_list
        ;

func_ident_list
        : IDENTIFIER
        | func_ident_list ',' IDENTIFIER
        ;

func_return_list
        : IDENTIFIER
        | '[' func_ident_list ']'
        ;

function_declare_lhs
        : IDENTIFIER
        | IDENTIFIER '(' ')'
        | IDENTIFIER '(' func_ident_list ')'
        ;

function_declare
        : function_declare_lhs
        | func_return_list '=' function_declare_lhs
        ;
Lovel answered 16/9, 2012 at 2:51 Comment(0)
L
7

I'm not sure when exactly it appeared (possibly Mar-Apr 2019), but it is now available on Mathworks' GitHub. Here's the grammar-defining xml file (as of 09-Apr-2019; compressed to avoid the SO post character limit):

Copyright 2018 The MathWorks, Inc., under the BSD2 license.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>fileTypes</key><array><string>m</string></array><key>keyEquivalent</key><string>^~M</string><key>name</key><string>MATLAB</string><key>patterns</key><array><dict><key>include</key><string>#classdef</string></dict><dict><key>include</key><string>#function</string></dict><dict><key>include</key><string>#blocks</string></dict><dict><key>include</key><string>#control_statements</string></dict><dict><key>include</key><string>#global_persistent</string></dict><dict><key>include</key><string>#command_dual</string></dict><dict><key>include</key><string>#string</string></dict><dict><key>include</key><string>#line_continuation</string></dict><dict><key>include</key><string>#comments</string></dict><dict><key>include</key><string>#transpose</string></dict><dict><key>include</key><string>#constants</string></dict><dict><key>include</key><string>#variables</string></dict><dict><key>include</key><string>#end_in_parens</string></dict><dict><key>include</key><string>#numbers</string></dict><dict><key>include</key><string>#operators</string></dict></array><key>repository</key><dict><key>blocks</key><dict><key>patterns</key><array><dict><key>begin</key><string>(^\s*)(for)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.for-quantity.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.for.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.for.matlab</string></dict></dict><key>name</key><string>meta.for.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.for-quantity.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(if)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.if-condition.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.if.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.if.matlab</string></dict></dict><key>name</key><string>meta.if.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.if-condition.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>captures</key><dict><key>0</key><dict><key>name</key><string>meta.elseif-condition.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.elseif.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict></dict><key>end</key><string>^</string><key>match</key><string>(^\s*)(elseif)\b(.*)$\n?</string><key>name</key><string>meta.elseif.matlab</string></dict><dict><key>captures</key><dict><key>0</key><dict><key>name</key><string>meta.else-condition.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.else.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict></dict><key>end</key><string>^</string><key>match</key><string>(^\s*)(else)\b(.*)?$\n?</string><key>name</key><string>meta.else.matlab</string></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(parfor)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.parfor-quantity.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.for.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.for.matlab</string></dict></dict><key>name</key><string>meta.parfor.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.parfor-quantity.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(spmd)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.spmd-statement.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.spmd.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.spmd.matlab</string></dict></dict><key>name</key><string>meta.spmd.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.spmd-statement.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(switch)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.switch-expression.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.switch.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.switch.matlab</string></dict></dict><key>name</key><string>meta.switch.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.switch-expression.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>captures</key><dict><key>0</key><dict><key>name</key><string>meta.case-expression.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.case.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict></dict><key>end</key><string>^</string><key>match</key><string>(^\s*)(case)\b(.*)$\n?</string><key>name</key><string>meta.case.matlab</string></dict><dict><key>captures</key><dict><key>0</key><dict><key>name</key><string>meta.otherwise-expression.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.otherwise.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict></dict><key>end</key><string>^</string><key>match</key><string>(^\s*)(otherwise)\b(.*)?$\n?</string><key>name</key><string>meta.otherwise.matlab</string></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(try)\b</string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>keyword.control.try.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.try.matlab</string></dict></dict><key>name</key><string>meta.try.matlab</string><key>patterns</key><array><dict><key>captures</key><dict><key>0</key><dict><key>name</key><string>meta.catch-exception.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.catch.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict></dict><key>end</key><string>^</string><key>match</key><string>(^\s*)(catch)\b(.*)?$\n?</string><key>name</key><string>meta.catch.matlab</string></dict><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(^\s*)(while)\b</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>meta.while-condition.matlab</string></dict><key>2</key><dict><key>name</key><string>keyword.control.while.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.while.matlab</string></dict></dict><key>name</key><string>meta.while.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G(?!$)</string><key>end</key><string>$\n?</string><key>name</key><string>meta.while-condition.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>include</key><string>$self</string></dict></array></dict></array></dict><key>classdef</key><dict><key>patterns</key><array><dict><key>begin</key><string>(?x)
                            (^\s*)                              # Leading whitespace
                            (classdef)
                            \b\s*
                            (                                   # Optional attributes
                                \( [^)]* \)
                            )?
                            \s*
                            (
                                ([a-zA-Z][a-zA-Z0-9_]*)         # Class name
                                (?:                             # Optional inheritance
                                    \s*
                                    (&lt;)
                                    \s*
                                    ([^%]*)
                                )?
                            )
                            \s*($|(?=%))
                        </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>storage.type.class.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>match</key><string>[a-zA-Z][a-zA-Z0-9_]*</string><key>name</key><string>variable.parameter.class.matlab</string></dict><dict><key>begin</key><string>=\s*</string><key>end</key><string>,|(?=\))</string><key>patterns</key><array><dict><key>match</key><string>true|false</string><key>name</key><string>constant.language.boolean.matlab</string></dict><dict><key>include</key><string>#string</string></dict></array></dict></array></dict><key>4</key><dict><key>name</key><string>meta.class-declaration.matlab</string></dict><key>5</key><dict><key>name</key><string>entity.name.section.class.matlab</string></dict><key>6</key><dict><key>name</key><string>keyword.operator.other.matlab</string></dict><key>7</key><dict><key>patterns</key><array><dict><key>match</key><string>[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)*</string><key>name</key><string>entity.other.inherited-class.matlab</string></dict><dict><key>match</key><string>&amp;</string><key>name</key><string>keyword.operator.other.matlab</string></dict></array></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.class.matlab</string></dict></dict><key>name</key><string>meta.class.matlab</string><key>patterns</key><array><dict><key>begin</key><string>(?x)
                                    (^\s*)                              # Leading whitespace
                                    (properties)\b(.*)$
                                    \s*
                                    (                                   # Optional attributes
                                        \( [^)]* \)
                                    )?
                                    \s*($|(?=%))
                                </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>keyword.control.properties.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>match</key><string>[a-zA-Z][a-zA-Z0-9_]*</string><key>name</key><string>variable.parameter.properties.matlab</string></dict><dict><key>begin</key><string>=\s*</string><key>end</key><string>,|(?=\))</string><key>patterns</key><array><dict><key>match</key><string>true|false</string><key>name</key><string>constant.language.boolean.matlab</string></dict><dict><key>match</key><string>public|protected|private</string><key>name</key><string>constant.language.access.matlab</string></dict></array></dict></array></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.properties.matlab</string></dict></dict><key>name</key><string>meta.properties.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(?x)
                                    (^\s*)                              # Leading whitespace
                                    (methods)\b(.*)$
                                    \s*
                                    (                                   # Optional attributes
                                        \( [^)]* \)
                                    )?
                                    \s*($|(?=%))
                                </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>keyword.control.methods.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>match</key><string>[a-zA-Z][a-zA-Z0-9_]*</string><key>name</key><string>variable.parameter.methods.matlab</string></dict><dict><key>begin</key><string>=\s*</string><key>end</key><string>,|(?=\))</string><key>patterns</key><array><dict><key>match</key><string>true|false</string><key>name</key><string>constant.language.boolean.matlab</string></dict><dict><key>match</key><string>public|protected|private</string><key>name</key><string>constant.language.access.matlab</string></dict></array></dict></array></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.methods.matlab</string></dict></dict><key>name</key><string>meta.methods.matlab</string><key>patterns</key><array><dict><key>include</key><string>$self</string></dict></array></dict><dict><key>begin</key><string>(?x)
                                    (^\s*)                              # Leading whitespace
                                    (events)\b(.*)$
                                    \s*
                                    (                                   # Optional attributes
                                        \( [^)]* \)
                                    )?
                                    \s*($|(?=%))
                                </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>keyword.control.events.matlab</string></dict><key>3</key><dict><key>patterns</key><array><dict><key>match</key><string>[a-zA-Z][a-zA-Z0-9_]*</string><key>name</key><string>variable.parameter.events.matlab</string></dict><dict><key>begin</key><string>=\s*</string><key>end</key><string>,|(?=\))</string><key>patterns</key><array><dict><key>match</key><string>true|false</string><key>name</key><string>constant.language.boolean.matlab</string></dict><dict><key>match</key><string>public|protected|private</string><key>name</key><string>constant.language.access.matlab</string></dict></array></dict></array></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.events.matlab</string></dict></dict><key>name</key><string>meta.events.matlab</string></dict><dict><key>begin</key><string>(?x)
                                    (^\s*)                              # Leading whitespace
                                    (enumeration)\b(.*)$
                                    \s*($|(?=%))
                                </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>keyword.control.enumeration.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.enumeration.matlab</string></dict></dict><key>name</key><string>meta.enumeration.matlab</string></dict><dict><key>include</key><string>$self</string></dict></array></dict></array></dict><key>command_dual</key><dict><key>captures</key><dict><key>1</key><dict><key>name</key><string>string.interpolated.matlab</string></dict><key>2</key><dict><key>name</key><string>variable.other.command.matlab</string></dict><key>28</key><dict><key>name</key><string>comment.line.percentage.matlab</string></dict></dict><key>comment</key><string>  1        2                                  3                                                    4                                                  5                                                    6                                                         7                                                                             8                 9                            10                   11                      12                         13                   14                                                               1516       17                                                             18                                                                                                                               19                      20                                     21                                    22                                      23                                         24                                         25                                                                         26            27                 28</string><key>match</key><string>^\s*((?# A&gt; )([b-df-hk-moq-zA-HJ-MO-Z]\w*|a|an|a([A-Za-mo-z0-9_]\w*|n[A-Za-rt-z0-9_]\w*|ns\w+)|e|ep|e([A-Za-oq-z0-9_]\w*|p[A-Za-rt-z0-9_]\w*|ps\w+)|in|i([A-Za-mo-z0-9_]\w*|n[A-Za-eg-z0-9_]\w*|nf\w+)|I|In|I([A-Za-mo-z0-9_]\w*|n[A-Za-eg-z0-9_]\w*|nf\w+)|j\w+|N|Na|N([A-Zb-z0-9_]\w*|a[A-MO-Za-z0-9_]\w*|aN\w+)|n|na|nar|narg|nargi|nargo|nargou|n([A-Zb-z0-9_]\w*|a([A-Za-mo-qs-z0-9_]\w*|n\w+|r([A-Za-fh-z0-9_]\w*|g([A-Za-hj-nq-z0-9_]\w*|i([A-Za-mo-z0-9_]\w*|n\w+)|o([A-Za-tv-z0-9_]\w*|u([A-Za-su-z]\w*|t\w+))))))|p|p[A-Za-hj-z0-9_]\w*|pi\w+)(?# &lt;A )\s+(((?# B&gt; )([^\s;,%()=.{&amp;|~&lt;&gt;:+\-*/\\@^'"]|(?=')|(?="))(?# &lt;B )|(?# C&gt; )(\.\^|\.\*|\./|\.\\|\.'|\.\(|&amp;&amp;|==|\|\||&amp;(?=[^&amp;])|\|(?=[^\|])|~=|&lt;=|&gt;=|~(?!=)|&lt;(?!=)|&gt;(?!=)|:|\+|-|\*|/|\\|@|\^)(?# &lt;C )(?# D&gt; )([^\s]|\s*(?=%)|\s+$|\s+(,|;|\)|}|\]|&amp;|\||&lt;|&gt;|=|:|\*|/|\\|\^|@|(\.[^\d.]|\.\.[^.])))(?# &lt;D )|(?# E&gt; )(\.[^^*/\\'(\sA-Za-z])(?# &lt;E ))(?# F&gt; )([^%]|'[^']*'|"[^"]*")*(?# &lt;F )|(?# X&gt; )(\.(?=\s)|\.[A-Za-z]|(?={))(?# &lt;X )(?# Y&gt; )([^(=\'"%]|==|'[^']*'|"[^"]*"|\(|\([^)%]*\)|\[|\[[^\]%]*\]|{|{[^}%]*})*(\.\.\.[^%]*)?((?=%)|$)(?# &lt;Y )))(%.*)?$</string></dict><key>comment_block</key><dict><key>begin</key><string>(^[\s]*)%\{[^\n\S]*+\n</string><key>beginCaptures</key><dict><key>1</key><dict><key>name</key><string>punctuation.definition.comment.matlab</string></dict></dict><key>end</key><string>^[\s]*%\}[^\n\S]*+(?:\n|$)</string><key>name</key><string>comment.block.percentage.matlab</string><key>patterns</key><array><dict><key>include</key><string>#comment_block</string></dict><dict><key>match</key><string>^[^\n]*\n</string></dict></array></dict><key>comments</key><dict><key>patterns</key><array><dict><key>begin</key><string>(^[ \t]+)?(?=%%\s)</string><key>beginCaptures</key><dict><key>1</key><dict><key>name</key><string>punctuation.whitespace.comment.leading.matlab</string></dict></dict><key>end</key><string>(?!\G)</string><key>patterns</key><array><dict><key>begin</key><string>%%</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.comment.matlab</string></dict></dict><key>end</key><string>\n</string><key>name</key><string>comment.line.double-percentage.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G[^\S\n]*(?![\n\s])</string><key>contentName</key><string>meta.cell.matlab</string><key>end</key><string>(?=\n)</string></dict></array></dict></array></dict><dict><key>include</key><string>#comment_block</string></dict><dict><key>begin</key><string>(^[ \t]+)?(?=%)</string><key>beginCaptures</key><dict><key>1</key><dict><key>name</key><string>punctuation.whitespace.comment.leading.matlab</string></dict></dict><key>end</key><string>(?!\G)</string><key>patterns</key><array><dict><key>begin</key><string>%</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.comment.matlab</string></dict></dict><key>end</key><string>\n</string><key>name</key><string>comment.line.percentage.matlab</string></dict></array></dict></array></dict><key>control_statements</key><dict><key>captures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.matlab</string></dict></dict><key>match</key><string>^\s*(break|continue|return)\b</string><key>name</key><string>meta.control.matlab</string></dict><key>function</key><dict><key>patterns</key><array><dict><key>begin</key><string>(?x)
                            (^\s*)                                              # Leading whitespace
                            (function)
                            \s+
                            (?:                                                 # Optional
                                (?:
                                    (\[) ([^\]]*) (\])
                                  | ([a-zA-Z][a-zA-Z0-9_]*)
                                )
                                \s* = \s*
                            )?
                            ([a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)*)   # Function name
                            \s*                                                 # Trailing space
                        </string><key>beginCaptures</key><dict><key>2</key><dict><key>name</key><string>storage.type.function.matlab</string></dict><key>3</key><dict><key>name</key><string>punctuation.definition.arguments.begin.matlab</string></dict><key>4</key><dict><key>patterns</key><array><dict><key>match</key><string>\w+</string><key>name</key><string>variable.parameter.output.matlab</string></dict></array></dict><key>5</key><dict><key>name</key><string>punctuation.definition.arguments.end.matlab</string></dict><key>6</key><dict><key>name</key><string>variable.parameter.output.function.matlab</string></dict><key>7</key><dict><key>name</key><string>entity.name.function.matlab</string></dict></dict><key>end</key><string>^\s*(end)\b(\s*\n)?</string><key>endCaptures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.end.function.matlab</string></dict></dict><key>name</key><string>meta.function.matlab</string><key>patterns</key><array><dict><key>begin</key><string>\G\(</string><key>end</key><string>\)</string><key>name</key><string>meta.arguments.function.matlab</string><key>patterns</key><array><dict><key>match</key><string>\w+</string><key>name</key><string>variable.parameter.input.matlab</string></dict></array></dict><dict><key>include</key><string>$self</string></dict></array></dict></array></dict><key>global_persistent</key><dict><key>captures</key><dict><key>1</key><dict><key>name</key><string>keyword.control.globalpersistent.matlab</string></dict></dict><key>match</key><string>^\s*(global|persistent)\b</string><key>name</key><string>meta.globalpersistent.matlab</string></dict><key>line_continuation</key><dict><key>captures</key><dict><key>1</key><dict><key>name</key><string>keyword.operator.symbols.matlab</string></dict><key>2</key><dict><key>name</key><string>comment.line.continuation.matlab</string></dict></dict><key>comment</key><string>Line continuations</string><key>match</key><string>(\.\.\.)(.*)$</string><key>name</key><string>meta.linecontinuation.matlab</string></dict><key>string</key><dict><key>patterns</key><array><dict><key>captures</key><dict><key>1</key><dict><key>name</key><string>string.interpolated.matlab</string></dict><key>2</key><dict><key>name</key><string>punctuation.definition.string.begin.matlab</string></dict></dict><key>comment</key><string>Shell command</string><key>match</key><string>^\s*((!).*$\n?)</string></dict><dict><key>begin</key><string>((?&lt;=(\[|\(|\{|=|\s|;|:|,|~|&lt;|&gt;|&amp;|\||-|\+|\*|/|\\|\.|\^))|^)'</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.matlab</string></dict></dict><key>comment</key><string>Character vector literal (single-quoted)</string><key>end</key><string>'(?=(\[|\(|\{|\]|\)|\}|=|~|&lt;|&gt;|&amp;|\||-|\+|\*|/|\\|\.|\^|\s|;|:|,))</string><key>endCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.string.end.matlab</string></dict></dict><key>name</key><string>string.quoted.single.matlab</string><key>patterns</key><array><dict><key>match</key><string>''</string><key>name</key><string>constant.character.escape.matlab</string></dict><dict><key>match</key><string>'(?=.)</string><key>name</key><string>invalid.illegal.unescaped-quote.matlab</string></dict><dict><key>comment</key><string>Operator symbols</string><key>match</key><string>((\%([\+\-0]?\d{0,3}(\.\d{1,3})?)(c|d|e|E|f|g|G|s|((b|t)?(o|u|x|X))))|\%\%|\\(b|f|n|r|t|\\))</string><key>name</key><string>constant.character.escape.matlab</string></dict></array></dict><dict><key>begin</key><string>((?&lt;=(\[|\(|\{|=|\s|;|:|,|~|&lt;|&gt;|&amp;|\||-|\+|\*|/|\\|\.|\^))|^)"</string><key>beginCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.string.begin.matlab</string></dict></dict><key>comment</key><string>String literal (double-quoted)</string><key>end</key><string>"(?=(\[|\(|\{|\]|\)|\}|=|~|&lt;|&gt;|&amp;|\||-|\+|\*|/|\\|\.|\^|\||\s|;|:|,))</string><key>endCaptures</key><dict><key>0</key><dict><key>name</key><string>punctuation.definition.string.end.matlab</string></dict></dict><key>name</key><string>string.quoted.double.matlab</string><key>patterns</key><array><dict><key>match</key><string>""</string><key>name</key><string>constant.character.escape.matlab</string></dict><dict><key>match</key><string>"(?=.)</string><key>name</key><string>invalid.illegal.unescaped-quote.matlab</string></dict></array></dict></array></dict><key>transpose</key><dict><key>match</key><string>((\w+)|(?&lt;=\])|(?&lt;=\)))\.?'</string><key>name</key><string>keyword.operator.transpose.matlab</string></dict><key>constants</key><dict><key>comment</key><string>MATLAB Constants</string><key>match</key><string>(?&lt;!\.)\b(eps|false|Inf|inf|intmax|intmin|namelengthmax|NaN|nan|on|off|realmax|realmin|true|pi)\b</string><key>name</key><string>constant.language.matlab</string></dict><key>variables</key><dict><key>comment</key><string>MATLAB variables</string><key>match</key><string>(?&lt;!\.)\b(nargin|nargout|varargin|varargout)\b</string><key>name</key><string>variable.other.function.matlab</string></dict><key>end_in_parens</key><dict><key>comment</key><string>end as operator symbol</string><key>match</key><string>\bend\b</string><key>name</key><string>keyword.operator.symbols.matlab</string></dict><key>numbers</key><dict><key>comment</key><string>Valid numbers: 1, .1, 1.1, .1e1, 1.1e1, 1e1, 1i, 1j, 1e2j</string><key>match</key><string>(?&lt;=[\s\-\+\*\/\\=:\[\(\{,]|^)\d*\.?\d+([eE][+-]?\d)?([0-9&amp;&amp;[^\.]])*(i|j)?\b</string><key>name</key><string>constant.numeric.matlab</string></dict><key>operators</key><dict><key>comment</key><string>Operator symbols</string><key>match</key><string>(?&lt;=\s)(==|~=|&gt;|&gt;=|&lt;|&lt;=|&amp;|&amp;&amp;|:|\||\|\||\+|-|\*|\.\*|/|\./|\\|\.\\|\^|\.\^)(?=\s)</string><key>name</key><string>keyword.operator.symbols.matlab</string></dict></dict><key>scopeName</key><string>source.matlab</string><key>uuid</key><string>48F8858B-72FF-11D9-BFEE-000D93589AF6</string></dict></plist>
Lustick answered 2/7, 2019 at 13:53 Comment(3)
Interesting find!Lightening
The first commit is Nov 2017, but it might have been made public later.Lightening
@CrisLuengo That's what I meant by "appeared", didn't find a better explanation at the time of writing :) It's been around for a while, though the latest version, which includes "-strings, went online at the end of March-2019. There's some more information about the current version here.Lustick
D
6

Excellent opportunity to write your own formal grammar :)

If you should choose to write the grammer your self, I can recommend BNFC which can take a formal BNF grammar and construct data structures and lexers/parsers for a couple of target languages (C/C++, C#, Java, Haskell etc.). This would save you a lot of time and let you focus on formulating the grammar, and then get right to implementing the converter in your language of preference.

If nothing else, the link to BNFC contains some help and pointers on how to formulate a BNF grammar. Best of luck!

Disrupt answered 6/3, 2012 at 12:7 Comment(2)
Thanks for the advice, I will have a look. I was thinking of using fslex and fsyacc.Hahnert
the link is broken!Toratorah
W
5

Dave Wingate provides some Antler resources that look like an excellent place to start. As noted in his README file, he doesn't include the transpose operator and a few other tricky parses. See the mparser link here:
http://web.mit.edu/~wingated/www/resources.html

Some of the tricky bits of earlier versions of Matlab ( 1999) are also described in a document by a group from Northwestern. It includes has EBNF-like descriptions. It also outlines some nasty bits in some footnotes.
http://www.ece.northwestern.edu/cpdc/pjoisha/MAGICA/CPDC-TR-9909-017.pdf

I've collected a couple of other less relevant sources, but stackoverflow's editor bot tells me I don't have enough reputation point to post more than two links.

Welldressed answered 6/7, 2014 at 20:54 Comment(1)
the first link is broken!Toratorah
C
4

You can start by adapting the MATLAB -> Python converter smop that is itself written in Python. It uses PLY (Python lex-yacc). The files you would likely be interested in starting from are lexer.py and parse.py.

See also this answer for a list of converters from MATLAB to Python.

Couvade answered 23/1, 2015 at 3:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.