⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 identerm.m

📁 一个matlab的将军模型
💻 M
字号:
function terminal = identerm(str)

% Identify `terminal symbols` to be parsed by the ACTL parser.
%
% Syntax:
%   "terminal = identerm(str)"
%
% Description:
%   Indentify the `terminal symbols` for the ACTL `grammar` in the input
%   string "str" and create the ouput cell array "terminal" of the
%   terminal symbols. There are 3 types of terminal symbols in our
%   implementation of the ACTL grammar
%
%   * `single characters`: "'~'","'&'","'|'","'('","')'","'X'","'F'",
%     "'G'","'U'","'R'","'A'"
%
%   * `equal sign`: "'=='"
%
%   * `name`: a string starting with a LOWERCASE alphabet followed by
%     LOWERCASE alphabets, numbers ("'1'", ..., "'9'"), or underscores
%     ('"_"').
%
%   Each terminal symbol in the output cell array is a structure with the
%   following fields
%
%   * "symbol", one of the single character symbols, "'=='", or "'name'".
%
%   * "production", the `production` in the ACTL grammar to be applied (see
%     help on function "parse.m"). This field is set to "'none'" for all
%     terminal symbols.
%
%   * "value". For `single charater` and `equal sign` symbols, this field
%     has the same value as the field "symbol". For the `name` symbols,
%     this field contains actual the name string for the symbol.
%
% See Also:
%   parse,compile_ap,build_ap,evaluate,model_check

terminal = {};

SPECIAL_CHARACTERS = {'~','&','|','(',')','X','F','G','U','R','A'};

% Implement the terminal identifier as a state machine.

SINGLE_CHARACTER  = 0;
NAME_ENTER        = 1;
NAME_DURING       = 2;
EQUAL_ENTER       = 4;
EQUAL_EXIT        = 5;

state = SINGLE_CHARACTER;
idx = 1;
while (idx <= length(str))
  ch = str(idx);
  
  % parser state transition
  switch state
    case {SINGLE_CHARACTER,EQUAL_EXIT}
      if islowercase(ch)
        state = NAME_ENTER;
      elseif ch == '=';
        state = EQUAL_ENTER;
      elseif ~(isspace(ch) | ismember(ch,SPECIAL_CHARACTERS))
        error([error_header(str,idx) 'Invalid character.'])
      else
        state = SINGLE_CHARACTER;
      end
    case {NAME_ENTER,NAME_DURING}
      if ismember(ch,SPECIAL_CHARACTERS) | isspace(ch)
        state = SINGLE_CHARACTER;
      elseif ch == '=';
        state = EQUAL_ENTER;
      elseif islowercase(ch) | isnumber(ch) | (ch == '_')
        state = NAME_DURING;
      else
        error([error_header(str,idx) ...
              'Invalid identifier name.']);
      end
    case EQUAL_ENTER
      if (ch == '=')
        state = EQUAL_EXIT;
      else
        error([error_header(str,idx) '= must be followed by another =.']);
      end
    otherwise
      error('Unknown parse state.')
  end
  
  % state action
  switch state
    case SINGLE_CHARACTER
      if ~isspace(ch)
        new = length(terminal)+1;
        terminal{new} = create_terminal(ch,ch);
      end
    case NAME_ENTER
      new = length(terminal)+1;
      terminal{new} = create_terminal('name',ch);
    case NAME_DURING
      last = length(terminal);
      terminal{last}.value = [terminal{last}.value ch];
    case EQUAL_ENTER
      ;
    case EQUAL_EXIT
      new = length(terminal)+1;
      terminal{new} = create_terminal('==','==');
    otherwise
      error('Unknown parse state.')
  end
  
  idx = idx + 1;
end

if state == EQUAL_ENTER
  error([error_header(str,idx-1) ...
        'Unfinished ''==''.']);
end

DEBUG = 0;
if DEBUG
  for k = 1:length(terminal)
    fprintf(1,'%s ',terminal{k}.value)
  end
  fprintf(1,'\n')
end

return

% -----------------------------------------------------------------------------

function terminal = create_terminal(symbol,value)

% This routine creates a terminal symbol node

terminal.symbol = symbol;
terminal.production = 'none';
terminal.value = value;
return

% -----------------------------------------------------------------------------

function st = islowercase(ch)

st = ('a' <= ch) & (ch <= 'z');
return

% -----------------------------------------------------------------------------

function st = isnumber(ch)

st = ('0' <= ch) & (ch <= '9');
return

% -----------------------------------------------------------------------------

function header = error_header(str,idx)

l1 = sprintf('%s...\n',str(1:idx));
l2 = sprintf('%s|\n',blanks(idx-1));
header = [l1 l2];
return

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -