/// <summary> /// コンストラクタ /// </summary> public NcCodeParser(NcCodeScanner scanner) { NcCodeToken tk; _Scanner = scanner; _Tokens = new List <NcCodeToken>(); while ((tk = scanner.GetToken()) != null) { _Tokens.Add(tk); } _Position = 0; _Token = _Position < _Tokens.Count ? _Tokens[_Position] : null; _LastCmdType = NcCodeCmdType.None; }
/// <summary> /// 指定の字句に対応する元テキストを取得する /// </summary> public string GetTokenString(NcCodeToken tk) { var line = _Lines[tk.LineIndex]; return(line.Substring(tk.Position, tk.Length)); }
/// <summary> /// 字句を取得する /// </summary> /// <returns>字句が返る、null なら終端まで到達したことを示す</returns> public NcCodeToken GetToken() { object data; while (_Line != null) { // 無駄な余白スキップ SkipSpace(_Line, ref _Position); // 字句の開始位置 var start = _Position; var c = GetCharAndNext(_Line, ref _Position); NcCodeToken t; int i; double d; try { switch (c) { case '\0': // 行末 NextLine(); break; case ';': // 行コメント t = new NcCodeToken(';', null, _LineIndex, start, _Line.Length - start); NextLine(); return(t); case '(': // コメント SkipToCommentEnd(_Line, ref _Position); return(new NcCodeToken(';', null, _LineIndex, start, _Position - start)); case 'G': case 'M': case 'N': case 'O': case 'P': case 'L': SkipSpace(_Line, ref _Position); i = GetInt(_Line, ref _Position); data = null; if (c == 'G' && i == 4) { // G04だけG04P...またはG04X...の様に続くコマンドがある // ... の部分には数字が入る SkipSpace(_Line, ref _Position); if (_Line.Length <= _Position) { throw new ApplicationException("G04に続く時間指定がありません。"); } var c2 = _Line[_Position]; if (c2 == 'P') { _Position++; if (_Line.Length <= _Position) { throw new ApplicationException("G04Pに続く数値がありません。"); } data = GetInt(_Line, ref _Position); } else { throw new ApplicationException("G04の時間指定はP(ミリ秒)以外はサポートしていません。"); } } return(new NcCodeToken(c, i.ToString(), data, _LineIndex, start, _Position - start)); case 'F': case 'S': case 'X': case 'Y': case 'Z': case 'I': case 'J': case 'K': case 'R': SkipSpace(_Line, ref _Position); d = GetDouble(_Line, ref _Position); return(new NcCodeToken(c, d.ToString(), _LineIndex, start, _Position - start)); case '/': return(new NcCodeToken(c, null, _LineIndex, start, _Position - start)); default: throw new ApplicationException("未対応のシンボル '" + c + "' が出現しました。"); } } catch (Exception ex) { throw new NcCodeTokenException(ex.Message, this); } } return(null); }
void NextToken() { _Position++; _Token = _Position < _Tokens.Count ? _Tokens[_Position] : null; }