OSDN Git Service

std::stol() などの std::out_of_range 例外をちゃんと処理するようにした
authorstarg <starg@users.osdn.me>
Tue, 6 Sep 2016 17:57:33 +0000 (02:57 +0900)
committerstarg <starg@users.osdn.me>
Tue, 6 Sep 2016 17:57:33 +0000 (02:57 +0900)
include/message/id.hpp
src/driver/msgcallback.cpp
src/parser/action_state_composition.hpp
src/parser/action_state_literal.hpp
src/parser/action_state_phrase.hpp
src/parser/pch.hpp

index 7a9627f..de21be8 100644 (file)
@@ -23,6 +23,7 @@ enum class MessageID : int
     TrackNumberIsOutOfSafeRange,
     TrackNumberIsOutOfPreferredRange,
     TooLargeRepeatCount,
+    IntegerOutOfRange,
     OctaveOutOfRange,
 
     // error_attribute.hpp
index 6e80c6f..dda7af8 100644 (file)
@@ -44,6 +44,7 @@ MessagePrinter::MessagePrinter(IStdErrWriter* pStdErrWriter)
         {Message::MessageID::TrackNumberIsOutOfSafeRange, "track number '{0}' is out of range (must be 0 <= # < {1})"},
         {Message::MessageID::TrackNumberIsOutOfPreferredRange, "track number '{0}' is out of range (must be 0 <= # < {1})"},
         {Message::MessageID::TooLargeRepeatCount, "repeat count '{0}' is too large (must be <= {1})"},
+        {Message::MessageID::IntegerOutOfRange, "integer literal '{0}' is out of range"},
         {Message::MessageID::OctaveOutOfRange, "octave value '{0}' is out of range (must be between 0 and 10)"},
 
         // error_attribute.hpp
index 9f150ca..40ea48e 100644 (file)
@@ -1,12 +1,14 @@
 
 #pragma once
 
+#include <stdexcept>
 #include <string>
 
 #include <pegtl.hh>
 
 #include <ast/composition.hpp>
 #include <ast/module.hpp>
+#include <message/message.hpp>
 #include <parser/parser.hpp>
 
 #include "action.hpp"
@@ -99,10 +101,25 @@ template<>
 class TrackBlockAction<Grammar::UnsignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, TrackBlockState& st, TCommonStates&...)
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, TrackBlockState& st, TCompiler& compiler, TCommonStates&...)
     {
-        st.ASTNode.TrackNumber = std::stoul(in.string());
+        try
+        {
+            st.ASTNode.TrackNumber = std::stoul(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
index ea7d51e..901dc24 100644 (file)
@@ -1,6 +1,7 @@
 
 #pragma once
 
+#include <stdexcept>
 #include <string>
 #include <utility>
 
@@ -27,6 +28,7 @@
 #endif
 
 #include <ast/literal.hpp>
+#include <message/message.hpp>
 
 #include "action.hpp"
 #include "parser_literal.hpp"
@@ -63,10 +65,25 @@ template<>
 class ValueAction<Grammar::SignedInteger>
 {
 public:
-    template<typename TState, typename... TCommonStates>
-    static void apply(const pegtl::input& in, TState& st, TCommonStates&...)
+    template<typename TState, typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, TState& st, TCompiler& compiler, TCommonStates&...)
     {
-        st.ASTNode.Value = std::stol(in.string());
+        try
+        {
+            st.ASTNode.Value = std::stol(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
index 8a55b53..8a07a0f 100644 (file)
@@ -2,6 +2,7 @@
 #pragma once
 
 #include <algorithm>
+#include <stdexcept>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -10,6 +11,7 @@
 
 #include <ast/module.hpp>
 #include <ast/phrase.hpp>
+#include <message/message.hpp>
 #include <parser/parser.hpp>
 
 #include "action.hpp"
@@ -215,10 +217,25 @@ template<>
 class NoteRepeatEachExpressionAction<Grammar::UnsignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, NoteRepeatEachExpressionState& st, TCommonStates&...)
-    {
-        st.ASTNode.Count = std::stoul(in.string());
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, NoteRepeatEachExpressionState& st, TCompiler& compiler, TCommonStates&...)
+    {
+        try
+        {
+            st.ASTNode.Count = std::stoul(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
@@ -253,10 +270,25 @@ template<>
 class NoteRepeatExpressionAction<Grammar::UnsignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, NoteRepeatExpressionState& st, TCommonStates&...)
-    {
-        st.ASTNode.Count = std::stoul(in.string());
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, NoteRepeatExpressionState& st, TCompiler& compiler, TCommonStates&...)
+    {
+        try
+        {
+            st.ASTNode.Count = std::stoul(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
@@ -428,10 +460,25 @@ template<>
 class SimpleDurationModifierAction<Grammar::UnsignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, SimpleDurationModifierState& st, TCommonStates&...)
-    {
-        st.ASTNode.Number = std::stoul(in.string());
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, SimpleDurationModifierState& st, TCompiler& compiler, TCommonStates&...)
+    {
+        try
+        {
+            st.ASTNode.Number = std::stoul(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
@@ -461,10 +508,25 @@ template<>
 class SimpleDurationAction<Grammar::UnsignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, SimpleDurationState& st, TCommonStates&...)
-    {
-        st.ASTNode.Number = std::stoul(in.string());
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, SimpleDurationState& st, TCompiler& compiler, TCommonStates&...)
+    {
+        try
+        {
+            st.ASTNode.Number = std::stoul(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
@@ -543,10 +605,25 @@ template<>
 class NoteOctaveAction<Grammar::SignedInteger>
 {
 public:
-    template<typename... TCommonStates>
-    static void apply(const pegtl::input& in, NoteOctaveState& st, TCommonStates&...)
-    {
-        st.ASTNode.Value = std::stoi(in.string());
+    template<typename TCompiler, typename... TCommonStates>
+    static void apply(const pegtl::input& in, NoteOctaveState& st, TCompiler& compiler, TCommonStates&...)
+    {
+        try
+        {
+            st.ASTNode.Value = std::stoi(in.string());
+        }
+        catch (const std::out_of_range&)
+        {
+            compiler.AddMessage(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::IntegerOutOfRange,
+                    compiler.GetSourceName(),
+                    {in.line(), in.column()},
+                    {in.string()}
+                }
+            );
+        }
     }
 };
 
index e221062..20179ae 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <stdexcept>
 #include <string>
 #include <type_traits>
 #include <utility>