Precedence resolution
This commit is contained in:
parent
4dd9fc7aeb
commit
3d6ff5d44d
11
TODO
11
TODO
|
@ -1,6 +1,10 @@
|
|||
-----------------------------------------------------------------------
|
||||
- TODO -
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
T> Parser selection without enum (Thomas) (flexible matching (case insensitive, ...))
|
||||
|
||||
R> Precedence resolution in generator
|
||||
R> Generated code error handler
|
||||
T> Parsodus regex parser in Lexesis
|
||||
-> Vrijgeven in libraryformaat: mogelijkheid verschillende tokens opvragen
|
||||
K> Parsodus Parsodus parser
|
||||
|
@ -36,3 +40,8 @@ R> man pages
|
|||
-> write configuration sets, table
|
||||
-> Generator: logging
|
||||
-> driver/main: debug flag
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
- DONE -
|
||||
-----------------------------------------------------------------------
|
||||
R> Precedence resolution in generator
|
||||
|
|
|
@ -7,17 +7,10 @@
|
|||
|
||||
namespace pds {
|
||||
|
||||
enum class PrecedenceType {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
NONASSOC
|
||||
};
|
||||
|
||||
struct Config {
|
||||
util::ParserType parserType;
|
||||
std::string lexesisFile;
|
||||
Grammar grammar;
|
||||
std::map<std::string, std::pair<int, PrecedenceType> > precedence; ///< lower value -> higher precedence
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@ namespace pds {
|
|||
Rule(const std::string& h, const std::vector<std::string>& t) : head(h), tail(t) {}
|
||||
};
|
||||
|
||||
enum class PrecedenceType {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
NONASSOC
|
||||
};
|
||||
|
||||
/**
|
||||
* A context free grammar
|
||||
* Keeps track of variables, terminals and replacement rules
|
||||
|
@ -40,6 +46,7 @@ namespace pds {
|
|||
std::set<std::string> variables; ///< the variables
|
||||
std::set<std::string> terminals; ///< the terminals
|
||||
std::vector<std::shared_ptr<Rule>> rules; ///< the replacement rules
|
||||
std::map<std::string, std::pair<int, PrecedenceType> > precedence; ///< lower value -> higher precedence
|
||||
|
||||
std::unique_ptr<util::FirstSet> first;
|
||||
std::unique_ptr<util::FollowSet> follow;
|
||||
|
|
|
@ -132,7 +132,39 @@ LRTable Generator<Itemset>::generate() {
|
|||
} else if (table.act[curIdx].count(term)) {
|
||||
if (table.act[curIdx][term].first == Action::SHIFT) {
|
||||
//Shift-Reduce conflict, rapport and resolve it (TODO)
|
||||
throw std::runtime_error("shift-reduce");
|
||||
std::string leftToken = "";
|
||||
for (std::size_t i = m_gram.rules[rule_applied]->tail.size(); i > 0; i--) {
|
||||
std::string leftSym = m_gram.rules[rule_applied]->tail[i - 1];
|
||||
if (m_gram.terminals.count(leftSym)) {
|
||||
leftToken = leftSym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
|
||||
auto leftTokenIt = m_gram.precedence.find(leftToken);
|
||||
auto rightTokenIt = m_gram.precedence.find(term);
|
||||
if (leftTokenIt != m_gram.precedence.end() && rightTokenIt != m_gram.precedence.end()) {
|
||||
if (leftTokenIt->second.first > rightTokenIt->second.first) {
|
||||
// Keep the shift
|
||||
handled = true;
|
||||
} else if (leftTokenIt->second.first > rightTokenIt->second.first) {
|
||||
// replace with a reduce
|
||||
table.act[curIdx][term] = {Action::REDUCE, rule_applied};
|
||||
handled = true;
|
||||
} else if (leftTokenIt->second.second == PrecedenceType::LEFT) {
|
||||
// replace with a reduce
|
||||
table.act[curIdx][term] = {Action::REDUCE, rule_applied};
|
||||
handled = true;
|
||||
} else if (leftTokenIt->second.second == PrecedenceType::RIGHT) {
|
||||
// Keep the shift
|
||||
handled = true;
|
||||
} //Nonassoc falls through
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
throw std::runtime_error("shift-reduce");
|
||||
} else if (table.act[curIdx][term].first == Action::REDUCE
|
||||
&& table.act[curIdx][term].second != rule_applied) {
|
||||
//Reduce-Reduce conflict, rapport it (TODO)
|
||||
|
|
Loading…
Reference in New Issue