@@ -287,7 +287,8 @@ inline std::string resolve_escape_sequence(const char *s, size_t n) {
287287 auto ch = s[i];
288288 if (ch == ' \\ ' ) {
289289 i++;
290- if (i == n) { throw std::runtime_error (" Invalid escape sequence..." ); }
290+ assert (i < n);
291+
291292 switch (s[i]) {
292293 case ' f' :
293294 r += ' \f ' ;
@@ -3369,6 +3370,17 @@ class ParserGenerator {
33693370 Data () : grammar(std::make_shared<Grammar>()) {}
33703371 };
33713372
3373+ class SyntaxErrorException : public std ::runtime_error {
3374+ public:
3375+ SyntaxErrorException (const char *what_arg, std::pair<size_t , size_t > r)
3376+ : std::runtime_error(what_arg), r_(r) {}
3377+
3378+ std::pair<size_t , size_t > line_info () const { return r_; }
3379+
3380+ private:
3381+ std::pair<size_t , size_t > r_;
3382+ };
3383+
33723384 void make_grammar () {
33733385 // Setup PEG syntax parser
33743386 g[" Grammar" ] <= seq (g[" Spacing" ], oom (g[" Definition" ]), g[" EndOfFile" ]);
@@ -3822,6 +3834,10 @@ class ParserGenerator {
38223834 auto s2 = std::any_cast<std::string>(vs[1 ]);
38233835 auto cp1 = decode_codepoint (s1.data (), s1.length ());
38243836 auto cp2 = decode_codepoint (s2.data (), s2.length ());
3837+ if (cp1 > cp2) {
3838+ throw SyntaxErrorException (" characer range is out of order..." ,
3839+ vs.line_info ());
3840+ }
38253841 return std::pair (cp1, cp2);
38263842 }
38273843 case 1 : {
@@ -4026,19 +4042,27 @@ class ParserGenerator {
40264042 }
40274043 }
40284044
4029- std::any dt = &data;
4030- auto r = g[" Grammar" ].parse (s, n, dt, nullptr , log);
4045+ try {
4046+ std::any dt = &data;
4047+ auto r = g[" Grammar" ].parse (s, n, dt, nullptr , log);
40314048
4032- if (!r.ret ) {
4033- if (log) {
4034- if (r.error_info .message_pos ) {
4035- auto line = line_info (s, r.error_info .message_pos );
4036- log (line.first , line.second , r.error_info .message ,
4037- r.error_info .label );
4038- } else {
4039- auto line = line_info (s, r.error_info .error_pos );
4040- log (line.first , line.second , " syntax error" , r.error_info .label );
4049+ if (!r.ret ) {
4050+ if (log) {
4051+ if (r.error_info .message_pos ) {
4052+ auto line = line_info (s, r.error_info .message_pos );
4053+ log (line.first , line.second , r.error_info .message ,
4054+ r.error_info .label );
4055+ } else {
4056+ auto line = line_info (s, r.error_info .error_pos );
4057+ log (line.first , line.second , " syntax error" , r.error_info .label );
4058+ }
40414059 }
4060+ return {};
4061+ }
4062+ } catch (const SyntaxErrorException &e) {
4063+ if (log) {
4064+ auto line = e.line_info ();
4065+ log (line.first , line.second , e.what (), " " );
40424066 }
40434067 return {};
40444068 }
@@ -4067,7 +4091,7 @@ class ParserGenerator {
40674091 if (log) {
40684092 auto line = line_info (s, ptr);
40694093 log (line.first , line.second ,
4070- " The definition '" + name + " ' is already defined." , " " );
4094+ " the definition '" + name + " ' is already defined." , " " );
40714095 }
40724096 }
40734097 ret = false ;
@@ -4079,7 +4103,7 @@ class ParserGenerator {
40794103 if (log) {
40804104 auto line = line_info (s, ptr);
40814105 log (line.first , line.second ,
4082- " The instruction '" + type + " ' is already defined." , " " );
4106+ " the instruction '" + type + " ' is already defined." , " " );
40834107 }
40844108 }
40854109 ret = false ;
@@ -4091,7 +4115,7 @@ class ParserGenerator {
40914115 if (log) {
40924116 auto line = line_info (s, ptr);
40934117 log (line.first , line.second ,
4094- " The back reference '" + name + " ' is undefined." , " " );
4118+ " the back reference '" + name + " ' is undefined." , " " );
40954119 }
40964120 }
40974121 ret = false ;
@@ -4107,7 +4131,7 @@ class ParserGenerator {
41074131 if (log) {
41084132 auto line = line_info (s, s);
41094133 log (line.first , line.second ,
4110- " The specified start rule '" + requested_start +
4134+ " the specified start rule '" + requested_start +
41114135 " ' is undefined." ,
41124136 " " );
41134137 }
@@ -4125,7 +4149,7 @@ class ParserGenerator {
41254149 if (log) {
41264150 auto line = line_info (s, start_rule.s_ );
41274151 log (line.first , line.second ,
4128- " Ignore operator cannot be applied to '" + start_rule.name + " '." ,
4152+ " ignore operator cannot be applied to '" + start_rule.name + " '." ,
41294153 " " );
41304154 }
41314155 ret = false ;
0 commit comments