hoa: preliminary implementation of a parser

* src/hoaparse/Makefile.am, src/hoaparse/fmterror.cc,
src/hoaparse/hoaparse.yy, src/hoaparse/hoascan.ll,
src/hoaparse/parsedecl.hh, src/hoaparse/public.hh: New files.
* src/Makefile.am, configure.ac, README: Adjust.
* src/tgbatest/ltl2tgba.cc: Add a -XH option.
* src/tgbatest/hoaparse.test: New file.
* src/tgbatest/Makefile.am: Adjust.
* buddy/src/bddx.h: Add a bdd_from_int() function.
This commit is contained in:
Alexandre Duret-Lutz 2014-11-18 18:48:36 +01:00
parent e1d4522ca9
commit e55bcd95aa
14 changed files with 1138 additions and 3 deletions

165
src/hoaparse/hoascan.ll Normal file
View file

@ -0,0 +1,165 @@
/* -*- coding: utf-8 -*-
** Copyright (C) 2014 Laboratoire de Recherche et Développement
** de l'Epita (LRDE).
**
** This file is part of Spot, a model checking library.
**
** Spot is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** Spot is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
** License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
%option noyywrap
%option prefix="hoayy"
%option outfile="lex.yy.c"
/* %option debug */
%{
#include <string>
#include "hoaparse/parsedecl.hh"
#define YY_USER_ACTION yylloc->columns(yyleng);
#define YY_NEVER_INTERACTIVE 1
typedef hoayy::parser::token token;
%}
eol \n+|\r+
eol2 (\n\r)+|(\r\n)+
identifier [[:alpha:]_][[:alnum:]_-]*
%x in_COMMENT in_STRING
%%
%{
std::string s;
yylloc->step();
%}
/* skip blanks and comments */
{eol} yylloc->lines(yyleng); yylloc->step();
{eol2} yylloc->lines(yyleng / 2); yylloc->step();
[ \t\v\f]+ yylloc->step();
"/*" BEGIN(in_COMMENT);
"//".* continue;
"\"" BEGIN(in_STRING);
"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;
"--END--" return token::END;
"State:" return token::STATE;
[tf{}()\[\]&|!] return *yytext;
{identifier} {
yylval->str = new std::string(yytext, yyleng);
return token::IDENTIFIER;
}
{identifier}":" {
yylval->str = new std::string(yytext, yyleng - 1);
return token::HEADERNAME;
}
"@"[[:alnum:]_-]+ {
yylval->str = new std::string(yytext + 1, yyleng - 1);
return token::ANAME;
}
[0-9]+ {
errno = 0;
unsigned long n = strtoul(yytext, 0, 10);
yylval->num = n;
if (errno || yylval->num != n)
{
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"value too large"));
yylval->num = 0;
}
return token::INT;
}
<in_COMMENT>{
[^*\n]* continue;
"*"+[^*/\n]* continue;
"\n"+ yylloc->end.column = 1; yylloc->lines(yyleng);
"*"+"/" BEGIN(INITIAL);
<<EOF>> {
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"unclosed comment"));
return 0;
}
}
<in_STRING>{
\" {
BEGIN(INITIAL);
yylval->str = new std::string(s);
return token::STRING;
}
\\\" s += '"';
\\. s += yytext[1];
[^\\\"]+ s.append(yytext, yyleng);
<<EOF>> {
error_list.push_back(
spot::hoa_parse_error(*yylloc,
"unclosed string"));
return 0;
}
}
. return *yytext;
%{
/* Dummy use of yyunput to shut up a gcc warning. */
(void) &yyunput;
%}
%%
namespace spot
{
int
hoayyopen(const std::string &name)
{
// yy_flex_debug = 1;
if (name == "-")
{
yyin = stdin;
}
else
{
yyin = fopen(name.c_str(), "r");
if (!yyin)
return 1;
}
// Reset the lexer in case a previous parse
// ended badly.
YY_NEW_FILE;
BEGIN(INITIAL);
return 0;
}
void
hoayyclose()
{
fclose(yyin);
}
}