-
-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Grammar Include Support #457
Changes from all commits
11e40ac
afb04cb
d64f080
e3c3212
920cadf
004df2a
50480e1
fb13e78
f2b87d9
7d04b35
3000e63
0eda407
7c293f7
4751dfc
4f2b480
7ef3fc0
87732d4
1e19398
63ab3c6
2936708
9073f4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
text=lf | ||
*.js linguist-vendored eol=lf |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"files.eol": "\n" | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1382,22 +1382,22 @@ describe('bootstrap', test => { | |
const ns = ohm.grammars(ohmGrammarSource); | ||
|
||
test('it can recognize arithmetic grammar', t => { | ||
assertSucceeds(t, ns.Ohm.match(arithmeticGrammarSource, 'Grammar')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Were these changes necessary, or is this an unrelated cleanup? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we added new |
||
assertSucceeds(t, ns.Ohm.match(arithmeticGrammarSource)); | ||
}); | ||
|
||
test('it can recognize itself', t => { | ||
assertSucceeds(t, ns.Ohm.match(ohmGrammarSource, 'Grammar')); | ||
assertSucceeds(t, ns.Ohm.match(ohmGrammarSource)); | ||
}); | ||
|
||
test('it can produce a grammar that works', t => { | ||
const g = buildGrammar(ns.Ohm.match(ohmGrammarSource, 'Grammar'), {}, ns.Ohm); | ||
const g = buildGrammar(ns.Ohm.match(ohmGrammarSource), {}, {}, ns.Ohm); | ||
assertSucceeds( | ||
t, | ||
g.match(ohmGrammarSource, 'Grammar'), | ||
g[0].match(ohmGrammarSource), | ||
'Ohm grammar can recognize itself', | ||
); | ||
const Arithmetic = buildGrammar(g.match(arithmeticGrammarSource, 'Grammar'), {}, g); | ||
const s = Arithmetic.createSemantics().addAttribute('v', { | ||
const Arithmetic = buildGrammar(g[0].match(arithmeticGrammarSource), {}, {}, g[0]); | ||
const s = Arithmetic[0].createSemantics().addAttribute('v', { | ||
exp(expr) { | ||
return expr.v; | ||
}, | ||
|
@@ -1438,13 +1438,63 @@ describe('bootstrap', test => { | |
return this.sourceString; | ||
}, | ||
}); | ||
t.is(s(Arithmetic.match('10*(2+123)-4/5')).v, 1249.2); | ||
t.is(s(Arithmetic[0].match('10*(2+123)-4/5')).v, 1249.2); | ||
}); | ||
|
||
test('full bootstrap!', t => { | ||
const g = buildGrammar(ns.Ohm.match(ohmGrammarSource, 'Grammar'), {}, ns.Ohm); | ||
const gPrime = buildGrammar(g.match(ohmGrammarSource, 'Grammar'), {}, g); | ||
const g = buildGrammar(ns.Ohm.match(ohmGrammarSource, 'Grammar'), {}, {}, ns.Ohm); | ||
const gPrime = buildGrammar(g.match(ohmGrammarSource, 'Grammar'), {}, {}, g); | ||
gPrime.namespaceName = g.namespaceName; // make their namespaceName properties the same | ||
compareGrammars(t, g, gPrime); | ||
}); | ||
}); | ||
|
||
describe('include', test => { | ||
test('include', t => { | ||
const g = ohm.grammar(` | ||
include 'test.ohm' | ||
`, {}, { | ||
fetchGrammar: (path) => `G { X = "G" }` | ||
}); | ||
|
||
assertSucceeds(t, g.match('G')); | ||
}); | ||
|
||
test('multiple', t => { | ||
const grammars = ohm.grammars(` | ||
include 'file-a.ohm' | ||
include 'file-b.ohm' | ||
`, {}, { | ||
fetchGrammar: (path) => { | ||
switch (path) { | ||
case "file-a.ohm": | ||
return 'FileA { A = "A" }'; | ||
|
||
case "file-b.ohm": | ||
return 'FileB { B = "B" }'; | ||
|
||
default: | ||
return ""; | ||
} | ||
} | ||
}); | ||
|
||
assertSucceeds(t, grammars.FileA.match('A')); | ||
assertSucceeds(t, grammars.FileB.match('B')); | ||
}); | ||
|
||
test('supergrammar', t => { | ||
const grammar = ohm.grammars(` | ||
include 'supergrammar.ohm' | ||
|
||
ChildGrammar <: SuperGrammar { | ||
S += "C" | ||
} | ||
`, {}, { | ||
fetchGrammar: (path) => 'SuperGrammar { S = "S" }' | ||
}); | ||
|
||
assertSucceeds(t, grammar.ChildGrammar.match('C')); | ||
assertSucceeds(t, grammar.ChildGrammar.match('S')); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[core] | ||
autocrlf = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for choosing to allow these specific characters? Maybe I'm wrong, but it seems like it may be overly restrictive.
An alternative would be for Ohm to be completely agnostic about paths, and accept any character inside the quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is following security standards to always use an allowlist when you know the expected content format. If you want to accept the risk and open it to any character between the quotes we can do that.