-- Copyright 2006-2019 Martin Morawetz. See License.txt. -- Matlab LPeg lexer. -- Based off of lexer code by Mitchell. local lexer = require('lexer') local token, word_match = lexer.token, lexer.word_match local P, R, S = lpeg.P, lpeg.R, lpeg.S local lex = lexer.new('matlab') -- Whitespace. lex:add_rule('whitespace', token(lexer.WHITESPACE, lexer.space^1)) -- Keywords. lex:add_rule('keyword', token(lexer.KEYWORD, word_match([[ break case catch continue do else elseif end end_try_catch end_unwind_protect endfor endif endswitch endwhile for function endfunction global if otherwise persistent replot return static switch try until unwind_protect unwind_protect_cleanup varargin varargout while ]], true))) -- Functions. lex:add_rule('function', token(lexer.FUNCTION, word_match[[ abs any argvatan2 axes axis ceil cla clear clf columns cos delete diff disp doc double drawnow exp figure find fix floor fprintf gca gcf get grid help hist hold isempty isnull length load log log10 loglog max mean median min mod ndims numel num2str ones pause plot printf quit rand randn rectangle rem repmat reshape round rows save semilogx semilogy set sign sin size sizeof size_equal sort sprintf squeeze sqrt std strcmp subplot sum tan tic title toc uicontrol who xlabel ylabel zeros ]])) -- Constants. lex:add_rule('constant', token(lexer.CONSTANT, word_match[[ EDITOR I IMAGEPATH INFO_FILE J LOADPATH OCTAVE_VERSION PAGER PS1 PS2 PS4 PWD ]])) -- Variable. lex:add_rule('variable', token(lexer.VARIABLE, word_match[[ ans automatic_replot default_return_value do_fortran_indexing define_all_return_values empty_list_elements_ok eps false gnuplot_binary ignore_function_time_stamp implicit_str_to_num_ok Inf inf NaN nan ok_to_lose_imaginary_part output_max_field_width output_precision page_screen_output pi prefer_column_vectors prefer_zero_one_indexing print_answer_id_name print_empty_dimensions realmax realmin resize_on_range_error return_last_computed_value save_precision silent_functions split_long_rows suppress_verbose_help_message treat_neg_dim_as_zero true warn_assign_as_truth_value warn_comma_in_global_decl warn_divide_by_zero warn_function_name_clash whitespace_in_literal_matrix ]])) -- Identifiers. lex:add_rule('identifier', token(lexer.IDENTIFIER, lexer.word)) -- Strings. lex:add_rule('string', token(lexer.STRING, lexer.delimited_range("'", true) + lexer.delimited_range('"') + lexer.delimited_range('`'))) -- Comments. local line_comment = (P('%') + '#') * lexer.nonnewline^0 local block_comment = '%{' * (lexer.any - '%}')^0 * P('%}')^-1 lex:add_rule('comment', token(lexer.COMMENT, block_comment + line_comment)) -- Numbers. lex:add_rule('number', token(lexer.NUMBER, lexer.float + lexer.integer + lexer.dec_num + lexer.hex_num + lexer.oct_num)) -- Operators. lex:add_rule('operator', token(lexer.OPERATOR, S('!%^&*()[]{}-=+/\\|:;.,?<>~`ยด'))) -- Fold points. lex:add_fold_point(lexer.KEYWORD, 'if', 'end') lex:add_fold_point(lexer.KEYWORD, 'for', 'end') lex:add_fold_point(lexer.KEYWORD, 'while', 'end') lex:add_fold_point(lexer.KEYWORD, 'switch', 'end') lex:add_fold_point(lexer.OPERATOR, '(', ')') lex:add_fold_point(lexer.OPERATOR, '[', ']') lex:add_fold_point(lexer.COMMENT, '%{', '%}') lex:add_fold_point(lexer.COMMENT, '%', lexer.fold_line_comments('%')) lex:add_fold_point(lexer.COMMENT, '#', lexer.fold_line_comments('#')) return lex