/// <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 List <NcCodeCmd> Parse() { try { var list = new List <NcCodeCmd>(); int code; bool skippable = false; while (_Token != null) { NcCodeCmd cmd = null; var oldCount = list.Count; switch (_Token.Symbol) { case 'G': // Gコード解析 code = Convert.ToInt32(_Token.Arg); switch (code) { case 0: // 位置決め _LastCmdType = NcCodeCmdType.G00; break; case 1: // 直線補間 _LastCmdType = NcCodeCmdType.G01; break; case 2: // 円弧補間(CW) _LastCmdType = NcCodeCmdType.G02; break; case 3: // 円弧補間(CCW) _LastCmdType = NcCodeCmdType.G03; break; case 4: // ドウェル ※ウェイト cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G04; cmd.Flags = NcCodeFlags.XYTime; cmd.XYTime = Convert.ToInt32(_Token.Data) / 1000.0; list.Add(cmd); break; case 17: // XY平面指定 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G17; list.Add(cmd); break; case 18: // ZX平面指定 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G18; list.Add(cmd); break; case 19: // YZ平面指定 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G19; list.Add(cmd); break; case 53: // 機械座標系選択 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G53; list.Add(cmd); break; case 90: // アブソリュート指令 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G90; list.Add(cmd); break; case 91: // インクリメンタル指令 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.G91; list.Add(cmd); break; case 92: // 座標系設定 _LastCmdType = NcCodeCmdType.G92; break; default: throw new ApplicationException("未対応のG" + code + "が出現しました。"); } NextToken(); break; case 'M': // Mコード解析 code = Convert.ToInt32(_Token.Arg); cmd = new NcCodeCmd(_Token.LineIndex); switch (code) { case 0: // プログラムストップ cmd.CmdType = NcCodeCmdType.M00; NextToken(); break; case 1: // オプショナルストップ cmd.CmdType = NcCodeCmdType.M01; NextToken(); break; case 2: // プログラムエンド cmd.CmdType = NcCodeCmdType.M02; NextToken(); break; case 10: // IO処理? cmd.CmdType = NcCodeCmdType.M10; NextToken(); break; case 20: // IO処理? cmd.CmdType = NcCodeCmdType.M20; NextToken(); break; case 98: // サブプログラム呼び出し cmd.CmdType = NcCodeCmdType.M98; NextToken(); ParseP(cmd); ParseL(cmd, true); break; case 99: // サブプログラム終了 cmd.CmdType = NcCodeCmdType.M99; NextToken(); break; default: throw new ApplicationException("未対応のM" + code + "が出現しました。"); } list.Add(cmd); break; case 'O': // サブプログラム番号 cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.O; cmd.Flags |= NcCodeFlags.P; cmd.P = Convert.ToInt32(_Token.Arg); list.Add(cmd); NextToken(); break; case 'X': case 'Y': case 'Z': // 軸指定 if (_LastCmdType == NcCodeCmdType.None) { throw new ApplicationException("Gコマンドでのモーダル開始前に軸の指定が出現しました。"); } cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = _LastCmdType; ParseAxis(cmd); if (_LastCmdType == NcCodeCmdType.G02 || _LastCmdType == NcCodeCmdType.G03) { ParseR(cmd); } ParseF(cmd, true); list.Add(cmd); break; case 'S': // スピンドル cmd = new NcCodeCmd(_Token.LineIndex); cmd.CmdType = NcCodeCmdType.S; cmd.S = Convert.ToDouble(_Token.Arg); list.Add(cmd); NextToken(); break; case ';': // コメントアウト NextToken(); break; case '/': // スキップ可能 NextToken(); skippable = true; break; default: throw new ApplicationException("未対応のコマンド '" + _Token.Symbol + "' が出現しました。"); } // スキップ可能状態の最中に新しいコマンドが来たらそれにスキップ可能フラグをセットする if (skippable && oldCount != list.Count) { skippable = false; list[oldCount].Flags |= NcCodeFlags.IsSkippable; } } return(list); } catch (Exception ex) { throw new NcCodeParserException(ex.Message, this); } }