hoa: swallow the neverclaim parser

This way we can easily parse a stream of HOAs intermixed with
neverclaims.

* src/hoaparse/hoaparse.yy, src/hoaparse/hoascan.ll: Add rules
for neverclaims, adjusted from src/neverparse/neverclaimparse.yy
and src/neverparse/neverclaimparse.ll.
* src/hoaparse/public.hh, NEWS: Update documentation.
* src/neverparse/: Remove this directory.
* README, configure.ac, src/Makefile.am: Adjust accordingly.
* src/tgbatest/ltl2tgba.cc, src/bin/ltlcross.cc: Use HOA
parser to read neverclaims.
* src/tgbatest/hoaparse.test, src/tgbatest/neverclaimread.test: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2014-12-03 18:20:35 +01:00
parent 39eefd0c6e
commit e1bba50047
18 changed files with 453 additions and 817 deletions

View file

@ -25,12 +25,16 @@
%{
#include <string>
#include "hoaparse/parsedecl.hh"
#include "misc/escape.hh"
#define YY_USER_ACTION yylloc->columns(yyleng);
#define YY_NEVER_INTERACTIVE 1
typedef hoayy::parser::token token;
static unsigned comment_level = 0;
static unsigned parent_level = 0;
static int orig_cond = 0;
static bool missing_parent = false;
%}
@ -38,7 +42,8 @@ eol \n+|\r+
eol2 (\n\r)+|(\r\n)+
identifier [[:alpha:]_][[:alnum:]_-]*
%x in_COMMENT in_STRING
%x in_COMMENT in_STRING in_NEVER_PAR
%s in_HOA in_NEVER
%%
@ -52,38 +57,48 @@ identifier [[:alpha:]_][[:alnum:]_-]*
{eol} yylloc->lines(yyleng); yylloc->step();
{eol2} yylloc->lines(yyleng / 2); yylloc->step();
[ \t\v\f]+ yylloc->step();
"/""*"+ BEGIN(in_COMMENT); comment_level = 1;
"\"" BEGIN(in_STRING);
"/""*"+ {
orig_cond = YY_START;
BEGIN(in_COMMENT);
comment_level = 1;
}
"\"" {
orig_cond = YY_START;
BEGIN(in_STRING);
comment_level = 1;
}
"HOA:" BEGIN(in_HOA); return token::HOA;
<INITIAL,in_HOA>"--ABORT--" BEGIN(INITIAL); throw spot::hoa_abort{*yylloc};
"never" BEGIN(in_NEVER); return token::NEVER;
"HOA:" return token::HOA;
"States:" return token::STATES;
"Start:" return token::START;
"AP:" return token::AP;
"Alias:" return token::ALIAS;
"Acceptance:" return token::ACCEPTANCE;
"acc-name:" return token::ACCNAME;
"tool:" return token::TOOL;
"name:" return token::NAME;
"properties:" return token::PROPERTIES;
"--BODY--" return token::BODY;
"--ABORT--" throw spot::hoa_abort{*yylloc};
"--END--" return token::END;
"State:" return token::STATE;
[tf{}()\[\]&|!] return *yytext;
<in_HOA>{
"States:" return token::STATES;
"Start:" return token::START;
"AP:" return token::AP;
"Alias:" return token::ALIAS;
"Acceptance:" return token::ACCEPTANCE;
"acc-name:" return token::ACCNAME;
"tool:" return token::TOOL;
"name:" return token::NAME;
"properties:" return token::PROPERTIES;
"--BODY--" return token::BODY;
"--END--" BEGIN(INITIAL); return token::END;
"State:" return token::STATE;
[tf{}()\[\]&|!] return *yytext;
{identifier} {
{identifier} {
yylval->str = new std::string(yytext, yyleng);
return token::IDENTIFIER;
}
{identifier}":" {
{identifier}":" {
yylval->str = new std::string(yytext, yyleng - 1);
return token::HEADERNAME;
}
"@"[[:alnum:]_-]+ {
"@"[[:alnum:]_-]+ {
yylval->str = new std::string(yytext + 1, yyleng - 1);
return token::ANAME;
}
[0-9]+ {
[0-9]+ {
errno = 0;
unsigned long n = strtoul(yytext, 0, 10);
yylval->num = n;
@ -96,6 +111,38 @@ identifier [[:alpha:]_][[:alnum:]_-]*
}
return token::INT;
}
}
<in_NEVER>{
"skip" return token::SKIP;
"if" return token::IF;
"fi" return token::FI;
"do" return token::DO;
"od" return token::OD;
"->" return token::ARROW;
"goto" return token::GOTO;
"false"|"0" return token::FALSE;
"atomic" return token::ATOMIC;
"assert" return token::ASSERT;
("!"[ \t]*)?"(" {
parent_level = 1;
BEGIN(in_NEVER_PAR);
yylval->str = new std::string(yytext, yyleng);
}
"true"|"1" {
yylval->str = new std::string(yytext, yyleng);
return token::FORMULA;
}
[a-zA-Z][a-zA-Z0-9_]* {
yylval->str = new std::string(yytext, yyleng);
return token::IDENTIFIER;
}
}
<in_COMMENT>{
"/""*"+ ++comment_level;
@ -103,7 +150,7 @@ identifier [[:alpha:]_][[:alnum:]_-]*
"/"[^*\n]* continue;
"*"+[^*/\n]* continue;
"\n"+ yylloc->end.column = 1; yylloc->lines(yyleng);
"*"+"/" if (--comment_level == 0) BEGIN(INITIAL);
"*"+"/" if (--comment_level == 0) BEGIN(orig_cond);
<<EOF>> {
error_list.push_back(
spot::hoa_parse_error(*yylloc,
@ -114,7 +161,7 @@ identifier [[:alpha:]_][[:alnum:]_-]*
<in_STRING>{
\" {
BEGIN(INITIAL);
BEGIN(orig_cond);
yylval->str = new std::string(s);
return token::STRING;
}
@ -128,6 +175,35 @@ identifier [[:alpha:]_][[:alnum:]_-]*
}
}
<in_NEVER_PAR>{
"(" {
++parent_level;
yylval->str->append(yytext, yyleng);
}
/* if we match ")&&(" or ")||(", stay in <in_NEVER_PAR> mode */
")"[ \t]*("&&"|"||")[ \t!]*"(" {
yylval->str->append(yytext, yyleng);
}
")" {
yylval->str->append(yytext, yyleng);
if (!--parent_level)
{
BEGIN(in_NEVER);
spot::trim(*yylval->str);
return token::FORMULA;
}
}
[^()]+ yylval->str->append(yytext, yyleng);
<<EOF>> {
unput(')');
if (!missing_parent)
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"missing closing parenthese"));
missing_parent = true;
}
}
. return *yytext;
%{
@ -158,6 +234,8 @@ namespace spot
YY_NEW_FILE;
BEGIN(INITIAL);
comment_level = 0;
parent_level = 0;
missing_parent = false;
return 0;
}