Skip to content

Commit

Permalink
adding more tests for zaach#205 / zaach#342
Browse files Browse the repository at this point in the history
  • Loading branch information
GerHobbelt committed Feb 11, 2017
1 parent 67556c0 commit 051dc5d
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 0 deletions.
112 changes: 112 additions & 0 deletions examples/issue-205-3.jison
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// A third way to observe the same LALR reduce/reduce conflict:
// the departure point for both rules (opt_prefix1 and opt_prefix2)
// is still the same, hence they land in the same state somewhere
// and then the union operation causes reduce/reduce havoc.


//%options on-demand-lookahead // camelCased: option.onDemandLookahead



%lex

%%

\s+ /* skip whitespace */
a return 'PREFIX1';
b return 'PREFIX2';
A return 'SUFFIX1';
B return 'SUFFIX2';
X return 'COMMON1';
. return 'ERROR';

/lex


%options no-default-action no-try-catch


%token PREFIX1 PREFIX2 SUFFIX1 SUFFIX2

%%

start:
opt_prefix1 SUFFIX1
| opt_prefix2 SUFFIX2
;

opt_prefix1:
c1
| PREFIX1
;

opt_prefix2:
c1
| PREFIX2
;

c1:
COMMON1
;

%%
// feature of the GH fork: specify your own main.
//
// compile with
//
// jison -o test.js --main that/will/be/me.jison
//
// then run
//
// node ./test.js
//
// to see the output.
var assert = require("assert");
parser.main = function () {
var testset_ok = ['XA', 'XB', 'aA', 'bB'];
var rv;
for (var i = 0, len = testset_ok.length; i < len; i++) {
try {
rv = parser.parse(testset_ok[i]);
console.log("test #" + i + ": '" + testset_ok[i] + "' ==> ", rv);
assert.equal(rv, true);
} catch (ex) {
console.log("test #" + i + ": '" + testset_ok[i] + "' ==> EXCEPTION: ", ex);
throw ex;
}
}
console.log("\nAnd now the failing inputs: even these deliver a result:\n");
// set up an aborting error handler which does not throw an exception
// but returns a special parse 'result' instead:
var errmsg = null;
var errReturnValue = false;
parser.yy.parseError = function (msg, hash) {
errmsg = msg;
return errReturnValue;
};
var testset_not_ok = ['a', 'b', 'aB', 'bA', '?', 'AA', 'BB', 'aa', 'bb', '?A', '?a'];
var base = i;
var rv;
for (var i = 0, len = testset_not_ok.length; i < len; i++) {
try {
rv = parser.parse(testset_not_ok[i]);
console.log("test #" + (base + i) + ": '" + testset_not_ok[i] + "' ==> ", rv);
assert.strictEqual(rv, errReturnValue);
} catch (ex) {
console.log("test #" + (base + i) + ": '" + testset_not_ok[i] + "' ==> EXCEPTION: ", ex);
throw ex;
}
}
// if you get past the assert(), you're good.
console.log("tested OK");
};
105 changes: 105 additions & 0 deletions examples/issue-205-4.jison
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// A LALR work-around for the reduce/reduce conflict:
// identify the two conflicting rules (opt_prefix1 and opt_prefix2)
// and **expand** them into their parent; then merge
// their common part in a single subrule (opt_prefix)



//%options on-demand-lookahead // camelCased: option.onDemandLookahead



%lex

%%

\s+ /* skip whitespace */
a return 'PREFIX1';
b return 'PREFIX2';
A return 'SUFFIX1';
B return 'SUFFIX2';
X return 'COMMON1';
. return 'ERROR';

/lex


%options no-default-action no-try-catch


%token PREFIX1 PREFIX2 SUFFIX1 SUFFIX2

%%

start:
opt_prefix SUFFIX1
| PREFIX1 SUFFIX2
| opt_prefix SUFFIX2
| PREFIX2 SUFFIX2
;

opt_prefix:
COMMON1
;

%%
// feature of the GH fork: specify your own main.
//
// compile with
//
// jison -o test.js --main that/will/be/me.jison
//
// then run
//
// node ./test.js
//
// to see the output.
var assert = require("assert");
parser.main = function () {
var testset_ok = ['XA', 'XB', 'aA', 'bB'];
var rv;
for (var i = 0, len = testset_ok.length; i < len; i++) {
try {
rv = parser.parse(testset_ok[i]);
console.log("test #" + i + ": '" + testset_ok[i] + "' ==> ", rv);
assert.equal(rv, true);
} catch (ex) {
console.log("test #" + i + ": '" + testset_ok[i] + "' ==> EXCEPTION: ", ex);
throw ex;
}
}
console.log("\nAnd now the failing inputs: even these deliver a result:\n");
// set up an aborting error handler which does not throw an exception
// but returns a special parse 'result' instead:
var errmsg = null;
var errReturnValue = false;
parser.yy.parseError = function (msg, hash) {
errmsg = msg;
return errReturnValue;
};
var testset_not_ok = ['a', 'b', 'aB', 'bA', '?', 'AA', 'BB', 'aa', 'bb', '?A', '?a'];
var base = i;
var rv;
for (var i = 0, len = testset_not_ok.length; i < len; i++) {
try {
rv = parser.parse(testset_not_ok[i]);
console.log("test #" + (base + i) + ": '" + testset_not_ok[i] + "' ==> ", rv);
assert.strictEqual(rv, errReturnValue);
} catch (ex) {
console.log("test #" + (base + i) + ": '" + testset_not_ok[i] + "' ==> EXCEPTION: ", ex);
throw ex;
}
}
// if you get past the assert(), you're good.
console.log("tested OK");
};

0 comments on commit 051dc5d

Please sign in to comment.