Avoid re-lexing, move position to internal state

Instead of passing around the current position as an argument, we now have a
parser property called pos to keep track of that.  Instead of repeatedly
re-lexing at the current position we now have a property called nextToken
which contains the token beginning at the current position.  We may need to
re-lex if we switch mode.  Since the position is kept in the parser state,
we don't need to return it from parsing methods, which obsoletes the
ParseResult class.
This commit is contained in:
Martin von Gagern
2015-06-29 11:45:40 +02:00
parent 5f275aa9c1
commit 4debcb34af
3 changed files with 209 additions and 239 deletions

View File

@@ -3,39 +3,37 @@ var parseData = require("./parseData");
var ParseError = require("./ParseError");
var ParseNode = parseData.ParseNode;
var ParseResult = parseData.ParseResult;
/**
* Parse the body of the environment, with rows delimited by \\ and
* columns delimited by &, and create a nested list in row-major order
* with one group per cell.
*/
function parseArray(parser, pos, result) {
function parseArray(parser, result) {
var row = [], body = [row], rowGaps = [];
while (true) {
var cell = parser.parseExpression(pos, false, null);
row.push(new ParseNode("ordgroup", cell.result, parser.mode));
pos = cell.position;
var next = cell.peek.text;
var cell = parser.parseExpression(false, null);
row.push(new ParseNode("ordgroup", cell, parser.mode));
var next = parser.nextToken.text;
if (next === "&") {
pos = cell.peek.position;
parser.consume();
} else if (next === "\\end") {
break;
} else if (next === "\\\\" || next === "\\cr") {
var cr = parser.parseFunction(pos);
rowGaps.push(cr.result.value.size);
pos = cr.position;
var cr = parser.parseFunction();
rowGaps.push(cr.value.size);
row = [];
body.push(row);
} else {
// TODO: Clean up the following hack once #385 got merged
var pos = Math.min(parser.pos + 1, parser.lexer._input.length);
throw new ParseError("Expected & or \\\\ or \\end",
parser.lexer, cell.peek.position);
parser.lexer, pos);
}
}
result.body = body;
result.rowGaps = rowGaps;
return new ParseResult(
new ParseNode(result.type, result, parser.mode), pos);
return new ParseNode(result.type, result, parser.mode);
}
/*
@@ -55,7 +53,6 @@ function parseArray(parser, pos, result) {
* - context: information and references provided by the parser
* - args: an array of arguments passed to \begin{name}
* The context contains the following properties:
* - pos: the current position of the parser.
* - envName: the name of the environment, one of the listed names.
* - parser: the parser object
* - lexer: the lexer object
@@ -90,8 +87,6 @@ defineEnvironment("array", {
numArgs: 1
}, function(context, args) {
var colalign = args[0];
var lexer = context.lexer;
var positions = context.positions;
colalign = colalign.value.map ? colalign.value : [colalign];
var cols = colalign.map(function(node) {
var ca = node.value;
@@ -108,14 +103,14 @@ defineEnvironment("array", {
}
throw new ParseError(
"Unknown column alignment: " + node.value,
lexer, positions[1]);
context.lexer, context.positions[1]);
});
var res = {
type: "array",
cols: cols,
hskipBeforeAndAfter: true // \@preamble in lttab.dtx
};
res = parseArray(context.parser, context.pos, res);
res = parseArray(context.parser, res);
return res;
});
@@ -142,10 +137,10 @@ defineEnvironment([
type: "array",
hskipBeforeAndAfter: false // \hskip -\arraycolsep in amsmath
};
res = parseArray(context.parser, context.pos, res);
res = parseArray(context.parser, res);
if (delimiters) {
res.result = new ParseNode("leftright", {
body: [res.result],
res = new ParseNode("leftright", {
body: [res],
left: delimiters[0],
right: delimiters[1]
}, context.mode);
@@ -173,9 +168,9 @@ defineEnvironment("cases", {
postgap: 0
}]
};
res = parseArray(context.parser, context.pos, res);
res.result = new ParseNode("leftright", {
body: [res.result],
res = parseArray(context.parser, res);
res = new ParseNode("leftright", {
body: [res],
left: "\\{",
right: "."
}, context.mode);