Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F80503254
libmultiscale_doc_parser.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Sep 1, 02:24
Size
12 KB
Mime Type
text/x-c++
Expires
Tue, Sep 3, 02:24 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
20382672
Attached To
rLIBMULTISCALE LibMultiScale
libmultiscale_doc_parser.cc
View Options
/**
* @file libmultiscale_doc_parser.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
*
* @date Fri Oct 10 16:40:09 2014
*
* @brief Manual parser
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "libmultiscale_doc_parser.hh"
/* -------------------------------------------------------------------------- */
#include <boost/version.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#if (BOOST_VERSION/100)%1000 <= 55
#include <boost/spirit/home/phoenix/bind/bind_member_function.hpp>
#include <boost/spirit/home/phoenix/bind/bind_function.hpp>
#else
#include <boost/phoenix/bind/bind_member_function.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#endif
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
#include <fstream>
#include <boost/filesystem.hpp>
using
namespace
boost
::
filesystem
;
/* -------------------------------------------------------------------------- */
using
namespace
boost
::
spirit
;
/* -------------------------------------------------------------------------- */
typedef
unsigned
int
UInt
;
/* -------------------------------------------------------------------------- */
#define _call(x) boost::phoenix::bind(&LibMultiScaleDocParser::x,this)
#define _call1(x,p1) boost::phoenix::bind(&LibMultiScaleDocParser::x,this,p1)
#define _call2(x,p1,p2) boost::phoenix::bind(&LibMultiScaleDocParser::x,this,p1,p2)
#define _call3(x,p1,p2,p3) boost::phoenix::bind(&LibMultiScaleDocParser::x,this,p1,p2,p3)
#define _call4(x,p1,p2,p3,p4) boost::phoenix::bind(&LibMultiScaleDocParser::x,this,p1,p2,p3,p4)
/* -------------------------------------------------------------------------- */
std
::
string
debug
(
const
std
::
string
&
v
){
std
::
cerr
<<
"AAAAAAAAAA "
<<
v
<<
" AAAAAAAAAAAAA"
<<
std
::
endl
;
return
v
;
}
#define _dbg(x,p1) boost::phoenix::bind(&debug,p1)
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
LibMultiScaleDocParser
()
:
LibMultiScaleDocParser
::
base_type
(
start
,
"start"
)
{
std
::
string
stag_desc
=
"/* LMDESC"
;
std
::
string
etag_desc
=
"*/"
;
std
::
string
stag_keyword
=
"/* LMKEYWORD"
;
std
::
string
etag_keyword
=
"*/"
;
std
::
string
stag_heritance
=
"/* LMHERITANCE"
;
std
::
string
etag_heritance
=
"*/"
;
std
::
string
stag_example
=
"/* LMEXAMPLE"
;
std
::
string
etag_example
=
"*/"
;
using
qi
::
char_
;
using
qi
::
print
;
using
qi
::
space
;
using
qi
::
alnum
;
using
qi
::
alpha
;
using
qi
::
string
;
using
qi
::
lexeme
;
using
qi
::
on_error
;
using
qi
::
fail
;
using
boost
::
phoenix
::
ref
;
using
boost
::
phoenix
::
val
;
using
boost
::
phoenix
::
construct
;
using
boost
::
phoenix
::
at_c
;
using
boost
::
phoenix
::
push_back
;
start
=
text
(
stag_desc
)
>
description
[
_val
=
_1
]
>>
*
(
*
(
char_
-
string
(
stag_keyword
)
-
string
(
stag_heritance
)
-
string
(
stag_example
))
>>
(
heritance
[
at_c
<
7
>
(
_val
)
=
_1
]
|
keyword
[
push_back
(
at_c
<
3
>
(
_val
),
_1
)]
|
example
[
at_c
<
8
>
(
_val
)
=
_1
]
)
);
lookup_todo
=
*
(
char_
-
string
(
"TODO"
))
>
eoi
;
lookup_type
=
*
(
string
(
"return"
)
|
(
char_
-
declaration
(
_r1
)))
>
declaration
(
_r1
)[
_val
=
_1
];
lookup_syntax
=
*
(
char_
-
string
(
"LMSYNTAX"
))
>
eoi
;
// quantity_type = string("Quantity<") > name > string(">");
vec_quantity_type
=
string
(
"Quantity<"
)
>
name
>
-
string
(
","
)
>
*
(
char_
-
'>'
)
>
string
(
">"
);
c_type
=
+
(
char_
-
"return"
-
eol
-
space
-
"{"
-
"}"
-
"<<"
-
">>"
);
declaration
=
(
vec_quantity_type
// | quantity_type
|
c_type
)[
_val
=
_1
]
>>
+
space
>>
string
(
_r1
)
>>
brackets
[
_val
+=
_1
]
>>
';'
;
brackets
=
-
(
string
(
"["
)
>
*
(
char_
-
string
(
"]"
))
>
string
(
"]"
));
description
=
lit
(
stag_desc
)
>
(
*
space
)
>
name
[
at_c
<
0
>
(
_val
)
=
_1
]
>
*
(
space
-
eol
)
>
eol
[
at_c
<
1
>
(
_val
)
=
val
(
"class"
)]
>
innertext
(
etag_desc
)[
at_c
<
2
>
(
_val
)
=
_1
]
>
lit
(
etag_desc
);
defaults
=
*
(
char_
-
')'
);
keyword
=
lit
(
stag_keyword
)
>
name
[
at_c
<
0
>
(
_val
)
=
_1
]
>
eol
>
innertext
(
etag_desc
)[
at_c
<
2
>
(
_val
)
=
_1
]
>
lit
(
etag_keyword
)
>
*
eol
>
(((
string
(
"this->parseTag"
)[
at_c
<
1
>
(
_val
)
=
"Tag"
]
|
string
(
"this->parseKeyword"
)[
at_c
<
1
>
(
_val
)
=
"Keyword"
]
)
>
"(
\"
"
>
string
(
at_c
<
0
>
(
_val
))
>
"
\"
,"
>
*
string
(
"this->"
)
>
name
[
at_c
<
4
>
(
_val
)
=
_1
]
>
*
(
char_
-
")"
-
","
)
>
-
(
string
(
","
)
>
defaults
[
at_c
<
9
>
(
_val
)
=
_1
]))
|
(
string
(
"this->parseVectorKeyword"
)[
at_c
<
1
>
(
_val
)
=
"Keyword ["
]
>
"(
\"
"
>
string
(
at_c
<
0
>
(
_val
))
>
"
\"
,"
>
expr
[
at_c
<
1
>
(
_val
)
+=
_1
+
val
(
std
::
string
(
"]"
))]
>
","
>
*
string
(
"this->"
)
>
name
[
at_c
<
4
>
(
_val
)
=
_1
]
>
-
(
string
(
","
)
>
string
(
"VEC_DEFAULTS("
)
>
defaults
[
at_c
<
9
>
(
_val
)
=
_1
]
>
string
(
")"
)))
)
>
string
(
");"
);
expr
=
*
(
char_
-
string
(
","
)
-
space
);
heritance
=
lit
(
stag_heritance
)
>
(
*
space
)
>
*
(
name
[
push_back
(
_val
,
_1
)]
>
*
(
space
-
eol
))
>
lit
(
etag_heritance
)
>
eol
;
example
=
lit
(
stag_example
)
>
(
*
space
)
>
*
(
char_
-
string
(
etag_example
))
>
lit
(
etag_example
)
>
eol
;
// parse everything but a starting tag
text
=
*
(
char_
-
string
(
_r1
));
// // parse a single name
name
=
+
(
alnum
|
string
(
"_"
));
// // parse everything but the end tag
innertext
=
*
(
char_
-
string
(
_r1
));
description
.
name
(
"description"
);
lookup_type
.
name
(
"lookup_type"
);
lookup_todo
.
name
(
"lookup_todo"
);
heritance
.
name
(
"heritance"
);
start
.
name
(
"start"
);
c_type
.
name
(
"c_type"
);
declaration
.
name
(
"declaration"
);
name
.
name
(
"name"
);
text
.
name
(
"text"
);
innertext
.
name
(
"innertext"
);
keyword
.
name
(
"keyword"
);
expr
.
name
(
"expr"
);
example
.
name
(
"example"
);
on_error
<
fail
>
(
start
,
_call4
(
errorHandlerMain
,
_1
,
_2
,
_3
,
_4
));
on_error
<
fail
>
(
lookup_type
,
_call4
(
errorHandlerMain
,
_1
,
_2
,
_3
,
_4
));
on_error
<
fail
>
(
lookup_todo
,
_call4
(
errorHandlerTodo
,
_1
,
_2
,
_3
,
_4
));
on_error
<
fail
>
(
lookup_syntax
,
_call4
(
errorHandlerSyntax
,
_1
,
_2
,
_3
,
_4
));
}
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
bool
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
parse
(
LMDocData
&
result
,
std
::
set
<
std
::
string
>
&
internal_key_list
){
fname
=
result
.
filename
.
native
();
std
::
ifstream
file
(
result
.
filename
.
c_str
());
if
(
!
file
.
good
())
std
::
cerr
<<
"could not open file: "
<<
result
.
filename
<<
std
::
endl
;
std
::
string
str
((
std
::
istreambuf_iterator
<
char
>
(
file
)),
std
::
istreambuf_iterator
<
char
>
());
iter
=
str
.
begin
();
end
=
str
.
end
();
bool
parsed
=
qi
::
phrase_parse
(
iter
,
end
,
start
,
boost
::
spirit
::
ascii
::
blank
,
result
);
result
.
filename
=
fname
;
if
(
result
.
example
==
""
&&
internal_key_list
.
count
(
result
.
name
)
==
0
){
std
::
cerr
<<
fname
<<
":0:Warning: no LMEXAMPLE found in that class"
<<
std
::
endl
;
}
else
if
(
result
.
example
!=
""
&&
internal_key_list
.
count
(
result
.
name
)
!=
0
){
std
::
cerr
<<
fname
<<
":0:Warning: an example was provided for an internal class"
<<
std
::
endl
;
}
if
(
!
parsed
)
return
parsed
;
iter
=
str
.
begin
();
std
::
string
todo
;
qi
::
parse
(
iter
,
end
,
lookup_todo
,
todo
);
if
(
!
parsed
)
return
parsed
;
iter
=
str
.
begin
();
std
::
string
syntax
;
qi
::
parse
(
iter
,
end
,
lookup_syntax
,
syntax
);
for
(
UInt
i
=
0
;
i
<
result
.
children
.
size
();
++
i
)
{
LMDocData
&
child
=
result
.
children
[
i
];
// if (child.type == "Tag" ||
// child.type == "Keyword" ||
// child.type == "Keyword []"){
path
cc_file
=
result
.
filename
;
path
hh_file
=
cc_file
.
replace_extension
(
path
(
".hh"
));
std
::
string
h_fname
=
hh_file
.
native
();
std
::
ifstream
hfile
(
h_fname
.
c_str
());
if
(
hfile
.
is_open
()
==
false
){
std
::
cerr
<<
"fname:0:Error: cannot find header file "
<<
h_fname
<<
std
::
endl
;
return
false
;
}
std
::
string
hstr
((
std
::
istreambuf_iterator
<
char
>
(
hfile
)),
std
::
istreambuf_iterator
<
char
>
());
iter
=
hstr
.
begin
();
end
=
hstr
.
end
();
std
::
string
c_type
;
// std::cerr << "look for parameter " << child.name << " " << child.var_name << " " << child.type << std::endl;
parsed
&=
qi
::
parse
(
iter
,
end
,
lookup_type
(
child
.
var_name
),
c_type
);
if
(
!
parsed
){
std
::
cerr
<<
h_fname
<<
":"
<<
0
<<
":Error could not parse variable "
<<
child
.
name
<<
" "
<<
child
.
var_name
<<
" "
<<
child
.
type
<<
std
::
endl
;
return
parsed
;
}
// std::cerr << "found parameter " << child.name << " " << child.var_name << " " << c_type << std::endl;
child
.
c_type
=
c_type
;
// }
iter
=
hstr
.
begin
();
std
::
string
todo
;
qi
::
parse
(
iter
,
end
,
lookup_todo
,
todo
);
if
(
!
parsed
)
return
parsed
;
iter
=
hstr
.
begin
();
std
::
string
syntax
;
qi
::
parse
(
iter
,
end
,
lookup_syntax
,
syntax
);
}
return
parsed
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
int
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
getLineNumber
(
const
std
::
string
&
text
,
std
::
string
&
now_parsing
){
int
last_index
=
0
;
UInt
count_lines
=
0
;
size_t
index
=
text
.
find_first_of
(
"
\n
"
,
0
);
while
(
index
!=
text
.
npos
){
count_lines
++
;
last_index
=
index
;
index
=
text
.
find_first_of
(
"
\n
"
,
last_index
+
1
);
// std::cerr << last_index << " " << index << std::endl;
}
// std::cerr << last_index << " " << index << std::endl;
now_parsing
=
text
.
substr
(
last_index
+
1
,
index
);
return
count_lines
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
void
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
errorHandlerMain
(
const
std
::
string
::
const_iterator
&
a
,
const
std
::
string
::
const_iterator
&
b
,
const
std
::
string
::
const_iterator
&
c
,
const
info
&
what
){
std
::
string
already_parsed
(
a
,
c
);
std
::
string
now_parsing
;
UInt
count_lines
=
getLineNumber
(
already_parsed
,
now_parsing
);
std
::
string
not_parsed
=
std
::
string
(
c
,
b
);
int
index
=
not_parsed
.
find_first_of
(
"
\n
"
,
0
);
std
::
string
mess
=
now_parsing
+
" ^^^^ "
+
not_parsed
.
substr
(
0
,
index
);
std
::
cerr
<<
fname
<<
":"
<<
count_lines
+
1
<<
":Error Expecting "
<<
what
<<
" here:
\"
"
<<
mess
<<
"
\"
"
<<
std
::
endl
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
void
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
errorHandlerTodo
(
const
std
::
string
::
const_iterator
&
a
,
const
std
::
string
::
const_iterator
&
b
,
const
std
::
string
::
const_iterator
&
c
,
const
info
&
what
){
std
::
string
already_parsed
(
a
,
c
);
// std::cerr << "already parsed " << already_parsed << std::endl;
std
::
string
now_parsing
;
UInt
count_lines
=
getLineNumber
(
already_parsed
,
now_parsing
);
std
::
cerr
<<
fname
<<
":"
<<
count_lines
+
1
<<
":Warning TODO remaining: "
<<
what
<<
": "
<<
now_parsing
<<
std
::
endl
;
}
/* -------------------------------------------------------------------------- */
template
<
typename
Iterator
,
typename
Skipper
>
void
LibMultiScaleDocParser
<
Iterator
,
Skipper
>::
errorHandlerSyntax
(
const
std
::
string
::
const_iterator
&
a
,
const
std
::
string
::
const_iterator
&
b
,
const
std
::
string
::
const_iterator
&
c
,
const
info
&
what
){
std
::
string
already_parsed
(
a
,
c
);
// std::cerr << "already parsed " << already_parsed << std::endl;
std
::
string
now_parsing
;
UInt
count_lines
=
getLineNumber
(
already_parsed
,
now_parsing
);
std
::
cerr
<<
fname
<<
":"
<<
count_lines
+
1
<<
":Warning old Syntax remaining: "
<<
what
<<
": "
<<
now_parsing
<<
std
::
endl
;
}
/* -------------------------------------------------------------------------- */
template
class
LibMultiScaleDocParser
<
std
::
string
::
const_iterator
>
;
Event Timeline
Log In to Comment