Skip to content

Commit 132ea95

Browse files
committed
wasm: update to latest liquid grammars, fix crash due to default start rule
1 parent 18c764c commit 132ea95

3 files changed

Lines changed: 36 additions & 10 deletions

File tree

packages/wasm/src/Compiler.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,12 @@ export class Compiler {
847847
Object.hasOwn(grammar.rules, name)
848848
);
849849
const rules = ownRuleNames.map(name => [name, lookUpRule(name)]);
850-
rules.push(['spaces', lookUpRule('spaces')]); // Ensure 'spaces' is always present.
850+
851+
// Ensure the certain rules are always included. (The default start rule
852+
// might be inherited from the supergrammar, so not there yet.)
853+
for (const name of ['spaces', grammar.defaultStartRule]) {
854+
rules.push([name, lookUpRule(name)]);
855+
}
851856

852857
const liftedTerminals = new IndexedSet();
853858

@@ -1045,7 +1050,11 @@ export class Compiler {
10451050

10461051
// Inline these. TODO: Handle this elsewhere.
10471052
// We need this to avoid having >256 rules in the Liquid grammar.
1048-
if (['liquidRawTagImpl', 'liquidTagRule'].includes(ruleName)) {
1053+
if (
1054+
['liquidRawTagImpl', 'liquidTagRule', 'anyExceptStar', 'anyExceptPlus'].includes(
1055+
ruleName
1056+
)
1057+
) {
10491058
return specialize(ir.substituteParams(ruleInfo.body, children));
10501059
}
10511060

packages/wasm/test/data/liquid-html.ohm

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ Liquid <: Helpers {
237237
// because we'd otherwise positively match the following string
238238
// instead of falling back to the other rule:
239239
// {{ 'string' | some_filter }}
240-
liquidVariable<delim> = liquidExpression<delim> liquidFilter<delim>* space* &delim
240+
liquidVariable<delim> = liquidComplexExpression<delim> liquidFilter<delim>* space* &delim
241241

242242
liquidExpression<delim> =
243243
| liquidString<delim>
@@ -246,6 +246,18 @@ Liquid <: Helpers {
246246
| liquidRange<delim>
247247
| liquidVariableLookup<delim>
248248

249+
liquidComplexExpression<delim> =
250+
| liquidBooleanExpression<delim>
251+
| liquidExpression<delim>
252+
253+
liquidBooleanExpression<delim> = booleanExpressionCondition<delim> listOf<booleanExpressionSubsequentCondition<delim>, conditionSeparator>
254+
255+
// This might over-capture things since the conditions below can contain any `liquidExpression`s.
256+
// We will need to clean this up in CST. If we restrict the conditions to only contain comparisons and
257+
// variable lookups, we can't support "truthy" expressions like `{{ some_var and 'this' }}`
258+
booleanExpressionSubsequentCondition<delim> = space* logicalOperator space* (comparison<delim> | liquidExpression<delim>) space*
259+
booleanExpressionCondition<delim> = comparison<delim> | liquidExpression<delim>
260+
249261
liquidString<delim> = liquidSingleQuotedString<delim> | liquidDoubleQuotedString<delim>
250262
liquidSingleQuotedString<delim> = "'" anyExceptStar<("'"| delim)> "'"
251263
liquidDoubleQuotedString<delim> = "\"" anyExceptStar<("\""| delim)> "\""

packages/wasm/test/test-liquid-html.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@ import {matchWithInput, unparse, toWasmGrammar} from './_helpers.js';
1010
const scriptRel = relPath => new URL(relPath, import.meta.url);
1111
const grammarSource = fs.readFileSync(scriptRel('data/liquid-html.ohm'), 'utf8');
1212

13-
const liquid = ohm.grammars(grammarSource);
13+
const grammars = ohm.grammars(grammarSource);
14+
15+
test('basic compilation', async t => {
16+
Object.values(grammars).forEach(async g => await toWasmGrammar(g));
17+
t.pass();
18+
});
1419

1520
test('basic matching (small)', async t => {
1621
const input = `---
1722
layout: default
1823
---
1924
{% assign year = page.started | date: '%Y' %}`;
20-
t.is(liquid.LiquidHTML.match(input).succeeded(), true);
25+
t.is(grammars.LiquidHTML.match(input).succeeded(), true);
2126

22-
const g = await toWasmGrammar(liquid.LiquidHTML);
27+
const g = await toWasmGrammar(grammars.LiquidHTML);
2328
t.is(matchWithInput(g, input), 1);
2429
t.is(unparse(g), input);
2530
});
@@ -31,25 +36,25 @@ test('swatch.liquid', async t => {
3136
class="{% if x == 'x' %}x{% endif %}"
3237
{% endif %}
3338
>`;
34-
const g = await toWasmGrammar(liquid.LiquidHTML);
39+
const g = await toWasmGrammar(grammars.LiquidHTML);
3540
t.is(matchWithInput(g, input), 1);
3641
});
3742

3843
test('html comment', async t => {
3944
const input = `{% if x %}
4045
<!-- x -->
4146
{% endif %}`;
42-
const g = await toWasmGrammar(liquid.LiquidHTML);
47+
const g = await toWasmGrammar(grammars.LiquidHTML);
4348
t.is(matchWithInput(g, input), 1);
4449
});
4550

4651
test('book-review.liquid', async t => {
4752
const input = fs.readFileSync(scriptRel('data/book-review.liquid'), 'utf8');
4853
let start = performance.now();
49-
t.is(liquid.LiquidHTML.match(input).succeeded(), true); // Trigger fillInputBuffer
54+
t.is(grammars.LiquidHTML.match(input).succeeded(), true); // Trigger fillInputBuffer
5055
t.log(`Ohm.js: ${(performance.now() - start).toFixed(2)}ms`);
5156

52-
const g = await toWasmGrammar(liquid.LiquidHTML);
57+
const g = await toWasmGrammar(grammars.LiquidHTML);
5358
start = performance.now();
5459
t.is(matchWithInput(g, input), 1);
5560
t.log(`Wasm: ${(performance.now() - start).toFixed(2)}ms`);

0 commit comments

Comments
 (0)