Clean up code and docs

release/4.3a0
Frank Dellaert 2023-02-04 14:52:28 -08:00
parent deafbdb3a7
commit d957d5e8f6
3 changed files with 90 additions and 52 deletions

View File

@ -18,7 +18,8 @@ inline static SignatureParser::Table ParseAnd() {
return {ParseFalseRow(), ParseFalseRow(), ParseFalseRow(), ParseTrueRow()};
}
bool static ParseConditional(const std::string& token, std::vector<double>& row) {
bool static ParseConditional(const std::string& token,
std::vector<double>& row) {
// Expect something like a/b/c
std::istringstream iss2(token);
try {
@ -35,7 +36,8 @@ bool static ParseConditional(const std::string& token, std::vector<double>& row)
return true;
}
void static ParseConditionalTable(const std::vector<std::string>& tokens, SignatureParser::Table& table) {
void static ParseConditionalTable(const std::vector<std::string>& tokens,
SignatureParser::Table& table) {
// loop over the words
// for each word, split it into doubles using a stringstream
for (const auto& word : tokens) {
@ -105,8 +107,8 @@ bool SignatureParser::parse(const std::string& str, Table& table) {
if (table.empty()) {
return false;
}
// the boost::phoenix parser did not return an error if we could not fully parse a string
// it just returned whatever it could parse
// the boost::phoenix parser did not return an error if we could not fully
// parse a string it just returned whatever it could parse
return true;
}
} // namespace gtsam

View File

@ -1,18 +1,19 @@
/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
* See LICENSE for the license information
* -------------------------------------------------------------------------- */
/**
* This is a simple parser that replaces the boost spirit parser. It is
* meant to parse strings like "1/1 2/3 1/4". Every word of the form "a/b/c/..."
* should be parsed as a row, and the rows should be stored in a table.
* The elements of the row will be doubles.
* The table is a vector of rows. The row is a vector of doubles.
* The parser should be able to parse the following strings:
* "1/1 2/3 1/4": {{1,1},{2,3},{1,4}}
* "1/1 2/3 1/4 1/1 2/3 1/4" : {{1,1},{2,3},{1,4},{1,1},{2,3},{1,4}}
* "1/2/3 2/3/4 1/2/3 2/3/4 1/2/3 2/3/4 1/2/3 2/3/4 1/2/3" : {{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3}}
* If the string has unparseable elements, the parser should parse whatever it can
* "1/2 sdf" : {{1,2}}
* It should return false if the string is empty.
* "": false
* We should return false if the rows are not of the same size.
* @file SignatureParser.h
* @brief Parser for conditional distribution signatures.
* @author Kartik Arcot
* @date January 2023
*/
#pragma once
@ -21,6 +22,30 @@
#include <vector>
namespace gtsam {
/**
* @brief A simple parser that replaces the boost spirit parser.
*
* It is meant to parse strings like "1/1 2/3 1/4". Every word of the form
* "a/b/c/..." is parsed as a row, and the rows are stored in a table.
*
* A `Row` is a vector of doubles, and a `Table` is a vector of rows.
*
* Examples: the parser is able to parse the following strings:
* "1/1 2/3 1/4":
* {{1,1},{2,3},{1,4}}
* "1/1 2/3 1/4 1/1 2/3 1/4" :
* {{1,1},{2,3},{1,4},{1,1},{2,3},{1,4}}
* "1/2/3 2/3/4 1/2/3 2/3/4 1/2/3 2/3/4 1/2/3 2/3/4 1/2/3" :
* {{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3},{2,3,4},{1,2,3}}
*
* If the string has un-parsable elements, should parse whatever it can:
* "1/2 sdf" : {{1,2}}
*
* It should return false if the string is empty:
* "": false
*
* We should return false if the rows are not of the same size.
*/
namespace SignatureParser {
typedef std::vector<double> Row;
typedef std::vector<Row> Table;

View File

@ -3,12 +3,16 @@
* @file testSimpleParser.cpp
*/
#include <CppUnitLite/TestHarness.h>
#include <gtsam/base/TestableAssertions.h>
#include <gtsam/discrete/SignatureParser.h>
#include <CppUnitLite/TestHarness.h>
bool compare_tables(const gtsam::SignatureParser::Table& table1,
const gtsam::SignatureParser::Table& table2) {
using namespace gtsam;
/* ************************************************************************* */
// Simple test case
bool compareTables(const SignatureParser::Table& table1,
const SignatureParser::Table& table2) {
if (table1.size() != table2.size()) {
return false;
}
@ -25,72 +29,79 @@ bool compare_tables(const gtsam::SignatureParser::Table& table1,
return true;
}
/* ************************************************************************* */
// Simple test case
TEST(SimpleParser, simple) {
gtsam::SignatureParser::Table table, expectedTable;
TEST(SimpleParser, Simple) {
SignatureParser::Table table, expectedTable;
expectedTable = {{1, 1}, {2, 3}, {1, 4}};
bool ret = gtsam::SignatureParser::parse("1/1 2/3 1/4", table);
bool ret = SignatureParser::parse("1/1 2/3 1/4", table);
EXPECT(ret);
// compare the tables
EXPECT(compare_tables(table, expectedTable));
EXPECT(compareTables(table, expectedTable));
}
/* ************************************************************************* */
// Test case with each row having 3 elements
TEST(SimpleParser, three_elements) {
gtsam::SignatureParser::Table table, expectedTable;
TEST(SimpleParser, ThreeElements) {
SignatureParser::Table table, expectedTable;
expectedTable = {{1, 1, 1}, {2, 3, 2}, {1, 4, 3}};
bool ret = gtsam::SignatureParser::parse("1/1/1 2/3/2 1/4/3", table);
bool ret = SignatureParser::parse("1/1/1 2/3/2 1/4/3", table);
EXPECT(ret);
// compare the tables
EXPECT(compare_tables(table, expectedTable));
EXPECT(compareTables(table, expectedTable));
}
// A test case to check if we can parse a signarue with 'T' and 'F'
TEST(SimpleParser, TandF) {
gtsam::SignatureParser::Table table, expectedTable;
expectedTable = {{1,0}, {1,0}, {1,0}, {0,1}};
bool ret = gtsam::SignatureParser::parse("F F F T", table);
/* ************************************************************************* */
// A test case to check if we can parse a signature with 'T' and 'F'
TEST(SimpleParser, TAndF) {
SignatureParser::Table table, expectedTable;
expectedTable = {{1, 0}, {1, 0}, {1, 0}, {0, 1}};
bool ret = SignatureParser::parse("F F F T", table);
EXPECT(ret);
// compare the tables
EXPECT(compare_tables(table, expectedTable));
EXPECT(compareTables(table, expectedTable));
}
/* ************************************************************************* */
// A test to parse {F F F 1}
TEST(SimpleParser, FFF1) {
gtsam::SignatureParser::Table table, expectedTable;
expectedTable = {{1,0}, {1,0}, {1,0}};
SignatureParser::Table table, expectedTable;
expectedTable = {{1, 0}, {1, 0}, {1, 0}};
// should ignore the last 1
bool ret = gtsam::SignatureParser::parse("F F F 1", table);
bool ret = SignatureParser::parse("F F F 1", table);
EXPECT(ret);
// compare the tables
EXPECT(compare_tables(table, expectedTable));
EXPECT(compareTables(table, expectedTable));
}
/* ************************************************************************* */
// Expect false if the string is empty
TEST(SimpleParser, empty_string) {
gtsam::SignatureParser::Table table;
bool ret = gtsam::SignatureParser::parse("", table);
TEST(SimpleParser, emptyString) {
SignatureParser::Table table;
bool ret = SignatureParser::parse("", table);
EXPECT(!ret);
}
// Expect false if jibberish
TEST(SimpleParser, jibberish) {
gtsam::SignatureParser::Table table;
bool ret = gtsam::SignatureParser::parse("sdf 22/3", table);
/* ************************************************************************* */
// Expect false if gibberish
TEST(SimpleParser, Gibberish) {
SignatureParser::Table table;
bool ret = SignatureParser::parse("sdf 22/3", table);
EXPECT(!ret);
}
// If jibberish is in the middle, it should still parse the rest
TEST(SimpleParser, jibberish_in_middle) {
gtsam::SignatureParser::Table table, expectedTable;
// If Gibberish is in the middle, it should still parse the rest
TEST(SimpleParser, GibberishInMiddle) {
SignatureParser::Table table, expectedTable;
expectedTable = {{1, 1}, {2, 3}};
bool ret = gtsam::SignatureParser::parse("1/1 2/3 sdf 1/4", table);
bool ret = SignatureParser::parse("1/1 2/3 sdf 1/4", table);
EXPECT(ret);
// compare the tables
EXPECT(compare_tables(table, expectedTable));
EXPECT(compareTables(table, expectedTable));
}
/* ************************************************************************* */
int main() {
TestResult tr;
return TestRegistry::runAllTests(tr);