forked from GitHub/gf-core
support for BIND/SOFT_BIND/SOFT_SPACE
This commit is contained in:
@@ -307,6 +307,7 @@ struct PGF_INTERNAL_DECL PgfLRReduce {
|
|||||||
struct PGF_INTERNAL_DECL PgfLRState {
|
struct PGF_INTERNAL_DECL PgfLRState {
|
||||||
ref<Vector<PgfLRShift>> shifts;
|
ref<Vector<PgfLRShift>> shifts;
|
||||||
ref<Vector<PgfLRShiftKS>> tokens;
|
ref<Vector<PgfLRShiftKS>> tokens;
|
||||||
|
size_t next_bind_state;
|
||||||
ref<Vector<PgfLRReduce>> reductions;
|
ref<Vector<PgfLRReduce>> reductions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -389,9 +389,11 @@ struct PgfLRTableMaker::State {
|
|||||||
std::map<Key1,State*,CompareKey1> ccats1;
|
std::map<Key1,State*,CompareKey1> ccats1;
|
||||||
std::map<Key2,State*,CompareKey2> ccats2;
|
std::map<Key2,State*,CompareKey2> ccats2;
|
||||||
std::map<Key3,State*,CompareKey3> tokens;
|
std::map<Key3,State*,CompareKey3> tokens;
|
||||||
|
State *bind_state;
|
||||||
|
|
||||||
State() {
|
State() {
|
||||||
this->id = 0;
|
this->id = 0;
|
||||||
|
this->bind_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~State() {
|
~State() {
|
||||||
@@ -693,6 +695,36 @@ void PgfLRTableMaker::symbol(State *state, Fold fold, Item *item, PgfSymbol sym)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PgfSymbolBIND::tag: {
|
||||||
|
if (fold != PROBE)
|
||||||
|
{
|
||||||
|
if (state->bind_state == NULL) {
|
||||||
|
state->bind_state = new State;
|
||||||
|
}
|
||||||
|
item->sym_idx++;
|
||||||
|
item->stk_size++;
|
||||||
|
state->bind_state->push_item(item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PgfSymbolSOFTBIND::tag:
|
||||||
|
case PgfSymbolSOFTSPACE::tag: {
|
||||||
|
if (fold != PROBE)
|
||||||
|
{
|
||||||
|
// SOFT_BIND && SOFT_SPACE also allow a space
|
||||||
|
item->sym_idx++;
|
||||||
|
process(state,fold,item);
|
||||||
|
|
||||||
|
// Now we handle the case where there is no space
|
||||||
|
if (state->bind_state == NULL) {
|
||||||
|
state->bind_state = new State;
|
||||||
|
}
|
||||||
|
item = new (item) Item();
|
||||||
|
item->stk_size++;
|
||||||
|
state->bind_state->push_item(item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (item->ref_cnt == 0)
|
if (item->ref_cnt == 0)
|
||||||
delete item;
|
delete item;
|
||||||
@@ -956,9 +988,9 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
while (!todo.empty()) {
|
while (!todo.empty()) {
|
||||||
State *state = todo.front(); todo.pop();
|
State *state = todo.front(); todo.pop();
|
||||||
|
|
||||||
//#if defined(DEBUG_AUTOMATON) || defined(DEBUG_STATE_CREATION)
|
#if defined(DEBUG_AUTOMATON) || defined(DEBUG_STATE_CREATION)
|
||||||
fprintf(stderr, "--------------- state %ld ---------------\n", state->id);
|
fprintf(stderr, "--------------- state %ld ---------------\n", state->id);
|
||||||
//#endif
|
#endif
|
||||||
|
|
||||||
while (!state->items.empty()) {
|
while (!state->items.empty()) {
|
||||||
Item *item = state->items.back(); state->items.pop_back();
|
Item *item = state->items.back(); state->items.pop_back();
|
||||||
@@ -1010,6 +1042,13 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
free(text);
|
free(text);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (state->bind_state != NULL) {
|
||||||
|
internalize_state(state->bind_state);
|
||||||
|
#if defined(DEBUG_AUTOMATON)
|
||||||
|
fprintf(stderr, "BIND: state %ld\n", state->bind_state->id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ref<PgfLRTable> lrtable = vector_new<PgfLRState>(states.size());
|
ref<PgfLRTable> lrtable = vector_new<PgfLRState>(states.size());
|
||||||
@@ -1043,6 +1082,11 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t next_bind_state = 0;
|
||||||
|
if (state->bind_state != NULL) {
|
||||||
|
next_bind_state = state->bind_state->id;
|
||||||
|
}
|
||||||
|
|
||||||
auto reductions = vector_new<PgfLRReduce>(state->completed.size());
|
auto reductions = vector_new<PgfLRReduce>(state->completed.size());
|
||||||
for (size_t i = 0; i < state->completed.size(); i++) {
|
for (size_t i = 0; i < state->completed.size(); i++) {
|
||||||
Item *item = state->completed[i];
|
Item *item = state->completed[i];
|
||||||
@@ -1066,6 +1110,7 @@ ref<PgfLRTable> PgfLRTableMaker::make()
|
|||||||
ref<PgfLRState> lrstate = vector_elem(lrtable, state->id);
|
ref<PgfLRState> lrstate = vector_elem(lrtable, state->id);
|
||||||
lrstate->shifts = shifts;
|
lrstate->shifts = shifts;
|
||||||
lrstate->tokens = tokens;
|
lrstate->tokens = tokens;
|
||||||
|
lrstate->next_bind_state = next_bind_state;
|
||||||
lrstate->reductions = reductions;
|
lrstate->reductions = reductions;
|
||||||
}
|
}
|
||||||
return lrtable;
|
return lrtable;
|
||||||
@@ -1190,8 +1235,7 @@ void PgfParser::print_transition(StackNode *source, StackNode *target, Stage *st
|
|||||||
printer.nprintf(64, "state %ld --- ", source->state_id);
|
printer.nprintf(64, "state %ld --- ", source->state_id);
|
||||||
if (target->choice != 0) {
|
if (target->choice != 0) {
|
||||||
printer.nprintf(32, "?%d", target->choice->fid);
|
printer.nprintf(32, "?%d", target->choice->fid);
|
||||||
}
|
} else if (shift != 0) {
|
||||||
if (shift != 0) {
|
|
||||||
size_t sym_idx = shift->sym_idx;
|
size_t sym_idx = shift->sym_idx;
|
||||||
ref<PgfSequence> seq = shift->seq;
|
ref<PgfSequence> seq = shift->seq;
|
||||||
while (sym_idx < seq->syms.len) {
|
while (sym_idx < seq->syms.len) {
|
||||||
@@ -1201,6 +1245,8 @@ void PgfParser::print_transition(StackNode *source, StackNode *target, Stage *st
|
|||||||
printer.symbol(sym);
|
printer.symbol(sym);
|
||||||
sym_idx++;
|
sym_idx++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
printer.puts("BIND");
|
||||||
}
|
}
|
||||||
printer.nprintf(80, " ---> state %ld (position %zu-%zu, nodes %zu)\n",
|
printer.nprintf(80, " ---> state %ld (position %zu-%zu, nodes %zu)\n",
|
||||||
target->state_id,
|
target->state_id,
|
||||||
@@ -1315,6 +1361,32 @@ void PgfParser::shift(StackNode *parent, Stage *before)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PgfParser::shift(StackNode *parent, Stage *before, Stage *after)
|
||||||
|
{
|
||||||
|
size_t next_bind_state = vector_elem(concr->lrtable,parent->state_id)->next_bind_state;
|
||||||
|
if (next_bind_state != 0) {
|
||||||
|
StackNode *node = NULL;
|
||||||
|
for (StackNode *n : after->nodes) {
|
||||||
|
if (n->stage == before && n->state_id == next_bind_state) {
|
||||||
|
node = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node == NULL) {
|
||||||
|
node = new StackNode(before, next_bind_state);
|
||||||
|
node->choice = NULL;
|
||||||
|
after->nodes.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::find(node->parents.begin(), node->parents.end(), parent) == node->parents.end()) {
|
||||||
|
node->parents.push_back(parent);
|
||||||
|
#ifdef DEBUG_PARSER
|
||||||
|
print_transition(parent,node,after,0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PgfParser::Choice *PgfParser::intersect_choice(Choice *choice1, Choice *choice2, intersection_map &im)
|
PgfParser::Choice *PgfParser::intersect_choice(Choice *choice1, Choice *choice2, intersection_map &im)
|
||||||
{
|
{
|
||||||
if (choice1 == NULL)
|
if (choice1 == NULL)
|
||||||
@@ -1482,6 +1554,18 @@ void PgfParser::space(PgfTextSpot *start, PgfTextSpot *end, PgfExn* err)
|
|||||||
|
|
||||||
before->end = *end;
|
before->end = *end;
|
||||||
|
|
||||||
|
if (before->next != NULL && before->start.pos==before->end.pos) {
|
||||||
|
after = new Stage(*end);
|
||||||
|
after->next = before;
|
||||||
|
size_t i = 0;
|
||||||
|
while (i < before->nodes.size()) {
|
||||||
|
StackNode *node = before->nodes[i++];
|
||||||
|
reduce_all(node);
|
||||||
|
shift(node, before, after);
|
||||||
|
}
|
||||||
|
before = after;
|
||||||
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < before->nodes.size()) {
|
while (i < before->nodes.size()) {
|
||||||
StackNode *node = before->nodes[i++];
|
StackNode *node = before->nodes[i++];
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ class PGF_INTERNAL_DECL PgfParser : public PgfPhraseScanner, public PgfExprEnum
|
|||||||
void shift(StackNode *parent, ref<PgfConcrLincat> lincat, size_t r, Production *prod,
|
void shift(StackNode *parent, ref<PgfConcrLincat> lincat, size_t r, Production *prod,
|
||||||
Stage *before, Stage *after);
|
Stage *before, Stage *after);
|
||||||
void shift(StackNode *parent, Stage *before);
|
void shift(StackNode *parent, Stage *before);
|
||||||
|
void shift(StackNode *parent, Stage *before, Stage *after);
|
||||||
void reduce(StackNode *parent, ref<PgfConcrLin> lin, ref<PgfLRReduce> red,
|
void reduce(StackNode *parent, ref<PgfConcrLin> lin, ref<PgfLRReduce> red,
|
||||||
size_t n, std::vector<Choice*> &args,
|
size_t n, std::vector<Choice*> &args,
|
||||||
Stage *before, Stage *after);
|
Stage *before, Stage *after);
|
||||||
|
|||||||
Reference in New Issue
Block a user