parse_aut: add support for #line

Fixes issue #232.

* spot/parseaut/parseaut.yy, spot/parseaut/public.hh,
spot/parseaut/scanaut.ll: Add support for #line.
* tests/core/parseaut.test: Test it.
* NEWS: Mention it.
This commit is contained in:
Alexandre Duret-Lutz 2021-04-16 18:04:41 +02:00
parent 093de290c1
commit 803a61a03d
5 changed files with 63 additions and 16 deletions

6
NEWS
View file

@ -191,6 +191,12 @@ New in spot 2.9.6.dev (not yet released)
setting SPOT_SIMULATION_REDUCTION environment variable or using the setting SPOT_SIMULATION_REDUCTION environment variable or using the
"-x simul-method=..." option (see spot-x(7)). "-x simul-method=..." option (see spot-x(7)).
- The automaton parser will now recognize lines of the form
#line 10 "filename"
that may occur *between* the automata of an input stream to specify
that error messages should be emitted as if the next automaton
was read from "filename" starting on line 10. (Issue #232)
Python: Python:
- Bindings for functions related to games. - Bindings for functions related to games.

View file

@ -255,6 +255,7 @@ extern "C" int strverscmp(const char *s1, const char *s2);
%token ACCPAIRS "Acceptance-Pairs:" %token ACCPAIRS "Acceptance-Pairs:"
%token ACCSIG "Acc-Sig:"; %token ACCSIG "Acc-Sig:";
%token ENDOFHEADER "---"; %token ENDOFHEADER "---";
%token <str> LINEDIRECTIVE "#line"
%left '|' %left '|'
@ -338,6 +339,10 @@ extern "C" int strverscmp(const char *s1, const char *s2);
%% %%
aut: aut-1 { res.h->loc = @$; YYACCEPT; } aut: aut-1 { res.h->loc = @$; YYACCEPT; }
/* Not how we do not accept garbage before LINEDIRECTIVE. This is because
all error will be relative to the specified filename, so that filename
must not be changed after any error was reported. */
| LINEDIRECTIVE { res.h->filename = *$1; } aut
| ENDOFFILE { YYABORT; } | ENDOFFILE { YYABORT; }
| error ENDOFFILE { YYABORT; } | error ENDOFFILE { YYABORT; }
| error aut-1 | error aut-1
@ -2635,6 +2640,7 @@ namespace spot
check_version(r); check_version(r);
last_loc = r.h->loc; last_loc = r.h->loc;
last_loc.step(); last_loc.step();
filename_ = r.h->filename; // in case it was changed
if (r.h->aborted) if (r.h->aborted)
{ {
if (opts_.ignore_abort) if (opts_.ignore_abort)

View file

@ -69,7 +69,7 @@ namespace spot
/// Format of the automaton. /// Format of the automaton.
parsed_aut_type type = parsed_aut_type::Unknown; parsed_aut_type type = parsed_aut_type::Unknown;
/// Name of the stream (used for displaying syntax errors) /// Name of the stream (used for displaying syntax errors)
const std::string filename; std::string filename;
/// \brief Syntax errors that occurred during parsing. /// \brief Syntax errors that occurred during parsing.
/// ///
/// Note that the parser does not print any diagnostic. /// Note that the parser does not print any diagnostic.

View file

@ -1,5 +1,5 @@
/* -*- coding: utf-8 -*- /* -*- coding: utf-8 -*-
** Copyright (C) 2014-2018, 2020 Laboratoire de Recherche et Développement ** Copyright (C) 2014-2018, 2020, 2021 Laboratoire de Recherche et Développement
** de l'Epita (LRDE). ** de l'Epita (LRDE).
** **
** This file is part of Spot, a model checking library. ** This file is part of Spot, a model checking library.
@ -90,6 +90,27 @@ identifier [[:alpha:]_][[:alnum:]_.-]*
BEGIN(in_COMMENT); BEGIN(in_COMMENT);
yyextra->comment_level = 1; yyextra->comment_level = 1;
} }
<INITIAL>"#line"[ \t]+[0-9]+[ \t]+\"[^\"\n]*\" {
errno = 0;
char* end;
unsigned long n = strtoul(yytext + 5, &end, 10);
yylval->num = n;
if (errno || yylval->num != n)
{
error_list.push_back(spot::parse_aut_error(*yylloc, "value too large")); }
else if (error_list.empty())
{
char* beg = strchr(end, '"');
end = strrchr(beg + 1, '"');
yylval->str = new std::string(beg + 1, end);
yylloc->initialize(nullptr, n - 1, yylloc->begin.column);
return token::LINEDIRECTIVE;
}
else
{
error_list.push_back(spot::parse_aut_error(*yylloc, "#line may not occur after any error"));
}
}
<INITIAL>"HOA:" BEGIN(in_HOA); return token::HOA; <INITIAL>"HOA:" BEGIN(in_HOA); return token::HOA;
<INITIAL,in_HOA>"--ABORT--" BEGIN(INITIAL); throw spot::hoa_abort{*yylloc}; <INITIAL,in_HOA>"--ABORT--" BEGIN(INITIAL); throw spot::hoa_abort{*yylloc};
<INITIAL>"never" BEGIN(in_NEVER); return token::NEVER; <INITIAL>"never" BEGIN(in_NEVER); return token::NEVER;

View file

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014-2018, 2020 Laboratoire de Recherche et Développement de # Copyright (C) 2014-2018, 2020-2021 Laboratoire de Recherche et
# l'Epita (LRDE). # Développement de l'Epita (LRDE).
# #
# This file is part of Spot, a model checking library. # This file is part of Spot, a model checking library.
# #
@ -69,6 +69,7 @@ input:2.1-9: ... previously defined here.
EOF EOF
cat >input <<EOF cat >input <<EOF
#line 1 "hoa"
HOA: v1 HOA: v1
States: 1 States: 1
Start: 0 Start: 0
@ -80,6 +81,7 @@ State: 0 {0}
State: 1 {0} State: 1 {0}
[t] 1 [t] 1
--END-- --END--
#line 1 "lbtt"
2 1t 2 1t
2 1 2 1
1 -1 "b" 1 -1 "b"
@ -103,17 +105,18 @@ EOF
diff='different state numbers have been used' diff='different state numbers have been used'
expecterr input <<EOF expecterr input <<EOF
input:8.5: state number is larger than state count... hoa:8.5: state number is larger than state count...
input:2.1-9: ... declared here. hoa:2.1-9: ... declared here.
input:9.8: state number is larger than state count... hoa:9.8: state number is larger than state count...
input:2.1-9: ... declared here. hoa:2.1-9: ... declared here.
input:10.5: state number is larger than state count... hoa:10.5: state number is larger than state count...
input:2.1-9: ... declared here. hoa:2.1-9: ... declared here.
input:12.1-19.2: 2 states have been declared, but 3 $diff lbtt:1.1-8.2: 2 states have been declared, but 3 $diff
input:25.5-10: non-Boolean transition label (replaced by true) lbtt:14.5-10: non-Boolean transition label (replaced by true)
EOF EOF
cat >input <<EOF cat >input <<EOF
#line 1 /* incomplete line directive */
HOA: v1 HOA: v1
States: 1 States: 1
Start: 0 Start: 0
@ -125,15 +128,22 @@ State: 0 {0}
State: 0 {0} State: 0 {0}
[t] 0 [t] 0
--END-- --END--
#line 1 "foo" /* line directive at the end is ignored */
EOF EOF
expecterr input <<EOF expecterr input <<EOF
input:8.2: AP number is larger than the number of APs... input:1.1: syntax error, unexpected invalid token
input:4.1-5: ... declared here input:9.2: AP number is larger than the number of APs...
input:9.1-8: redeclaration of state 0 input:5.1-5: ... declared here
input:10.1-8: redeclaration of state 0
input:1.1-7: leading garbage was ignored
EOF EOF
cat >input <<EOF cat >input <<EOF
#line 0 invalid
#line -0 "invalid"
#line 99999999999999 "too large"
#line 1 "real"
HOA: v1 HOA: v1
States: 0 States: 0
AP: 1 "a" "b" AP: 1 "a" "b"
@ -143,7 +153,11 @@ Acceptance: 0 t
EOF EOF
expecterr input <<EOF expecterr input <<EOF
input:3.1-13: found 2 atomic propositions instead of the 1 announced input:1.1: syntax error, unexpected invalid token
input:3.1-32: value too large
input:4.1-14: #line may not occur after any error
input:7.1-13: found 2 atomic propositions instead of the 1 announced
input:1.1-2.18: leading garbage was ignored
EOF EOF
cat >input <<EOF cat >input <<EOF