-
Notifications
You must be signed in to change notification settings - Fork 0
/
value_disambiguator.cpp
81 lines (72 loc) · 2.35 KB
/
value_disambiguator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (C) 2012 Mario Lang <mlang@delysid.org>
//
// Distributed under the terms of the GNU General Public License version 3.
// (see accompanying file LICENSE.txt or copy at
// http://www.gnu.org/licenses/gpl-3.0-standalone.html)
#include <sstream>
#include "bmc/braille/semantic_analysis/value_disambiguator.hpp"
#include "bmc/braille/semantic_analysis/value_disambiguation.hpp"
namespace music { namespace braille {
value_disambiguator::value_disambiguator(report_error_type const& report_error)
: compiler_pass(report_error)
, time_signature(4, 4)
, prev_duration(0)
, anacrusis(new value_disambiguation::measure_interpretations())
{}
value_disambiguator::result_type
value_disambiguator::operator()(ast::measure& measure)
{
value_disambiguation::measure_interpretations
interpretations(measure, time_signature, prev_duration);
if (not interpretations.contains_complete_measure() and
not interpretations.empty()) {
if (anacrusis->empty()) {
*anacrusis = interpretations;
prev_duration = 0;
return true;
} else {
if (anacrusis->completes_uniquely(interpretations)) {
for (auto& lhs: *anacrusis) {
for (auto& rhs: interpretations) {
if (duration(lhs) + duration(rhs) == time_signature) {
lhs.accept(), rhs.accept();
prev_duration = duration(rhs);
anacrusis->clear();
return true;
}
}
}
}
}
}
if (interpretations.size() == 1) {
interpretations.front().accept();
prev_duration = duration(interpretations.front());
return true;
}
if (interpretations.empty()) {
report_error(measure.id, L"No possible interpretations");
} else {
std::wstringstream s;
s << interpretations.size() << L" possible interpretations:";
for (auto& interpretation: interpretations) {
rational const score(interpretation.harmonic_mean());
s << std::endl
<< boost::rational_cast<float>(score) << L": " << interpretation;
}
report_error(measure.id, s.str());
}
return false;
}
bool
value_disambiguator::end_of_staff() const {
if (anacrusis->size() > 1) {
std::wstringstream msg;
msg << "Unterminated anacrusis";
report_error(anacrusis->get_measure_id(), msg.str());
return false;
}
if (not anacrusis->empty()) anacrusis->front().accept();
return true;
}
}}