-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic functionality reproduced in Astro
- Loading branch information
Showing
12 changed files
with
215 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
"astro": "astro" | ||
}, | ||
"dependencies": { | ||
"astro": "^5.0.3" | ||
"astro": "^5.0.3", | ||
"ppegjs": "0.1.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {defineCollection, z} from 'astro:content'; | ||
|
||
|
||
// Examples should be like this: | ||
// examples/foo/grammar.txt | ||
// examples/foo/input.txt | ||
// TODO: convert to markdown, if astro is happy with multiple files in a single markdown file - easier to do titles too | ||
export const examples = defineCollection({ | ||
loader: async () => { | ||
// Would prefer to get a list of folders in the examples directory but Vite only seems to want to | ||
// grab files. So we get both and match them up, a little awkwardly. | ||
const grammars = import.meta.glob('./examples/**/grammar.txt', { query: "?raw", import: "default"}) | ||
const inputs = import.meta.glob('./examples/**/input.txt', { query: "?raw", import: "default"}) | ||
if (Object.keys(grammars).length !== Object.keys(inputs).length) { | ||
throw new Error('Mismatch between grammars and inputs') | ||
} | ||
const examples: { id: string, title: string, grammar: string, input: string }[] = [] | ||
for (const [path, grammarFile] of Object.entries(grammars)) { | ||
const folder = path.split('/').slice(-2, -1)[0] | ||
const grammar = await grammarFile() as string | ||
// yuck... | ||
const input = await inputs[`./examples/${folder}/input.txt`]() as string | ||
examples.push({ | ||
id: folder, | ||
title: folder, | ||
grammar, | ||
input, | ||
}) | ||
} | ||
return examples; | ||
}, | ||
// This schema ensures that the data read in the collection above is valid, by parsing it with Zod | ||
schema: z.object({ | ||
title: z.string(), | ||
grammar: z.string(), | ||
input: z.string(), | ||
}) | ||
}); | ||
|
||
export const collections = {examples}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
CSV = Hdr Row+ | ||
Hdr = Row | ||
Row = field (',' field)* '\r'? '\n' | ||
field = _string / _text / '' | ||
|
||
_text = ~[,\n\r]+ | ||
_string = '"' (~["] / '""')* '"' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
A,B,C | ||
a1,b1,c1 | ||
a2,"b,2",c2 | ||
a3,b3,c3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
date = year '-' month '-' day | ||
year = [1-2][0-9]*3 | ||
month = '0'[1-9] / '1'[0-2] | ||
day = [0-3][0-9] | ||
|
||
# A simple example to play around with. | ||
# More examples in menu at top. | ||
|
||
# This Dingus is only a toy web-page. | ||
# To try your own pPEG grammars use | ||
# the peg-play.mjs command line tool, | ||
# that lets you work on your own files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
2021-02-03 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
json = _ value _ | ||
value = Str / Arr / Obj / num / lit | ||
Obj = '{'_ (memb (_','_ memb)*)? _'}' | ||
memb = Str _':'_ value | ||
Arr = '['_ (value (_','_ value)*)? _']' | ||
Str = '"' chars* '"' | ||
chars = ~[\u0000-\u001F"\]+ / '\' esc | ||
esc = ["\/bfnrt] / 'u' [0-9a-fA-F]*4 | ||
num = _int _frac? _exp? | ||
_int = '-'? ([1-9] [0-9]* / '0') | ||
_frac = '.' [0-9]+ | ||
_exp = [eE] [+-]? [0-9]+ | ||
lit = 'true' / 'false' / 'null' | ||
_ = [ \t\n\r]* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"answer": 42, | ||
"mixed": [1, 2.3, "a\tstring", true, [4, 5]], | ||
"empty": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Equivalent to the regular expression for | ||
# well-formed URI's in RFC 3986. | ||
URI = (scheme ':')? ('//' auth)? | ||
path ('?' query)? ('#' frag)? | ||
scheme = ~[:/?#]+ | ||
auth = ~[/?#]* | ||
path = ~[?#]* | ||
query = ~'#'* | ||
frag = ~[ \t\n\r]* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
http://www.ics.uci.edu/pub/ietf/uri/#Related |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,125 @@ | ||
--- | ||
import Welcome from '../components/Welcome.astro'; | ||
import Layout from '../layouts/Layout.astro'; | ||
// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build | ||
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh. | ||
import {getCollection} from "astro:content" | ||
const examples = (await getCollection("examples")).map(c => c.data) | ||
--- | ||
|
||
<script> | ||
import {ppeg} from "ppegjs/index.js" | ||
|
||
window.dingus = { | ||
eg: () => { | ||
const eg = document.getElementById('examples'), | ||
grammar = document.getElementById('grammar'), | ||
input = document.getElementById('input'); | ||
grammar.textContent = document.getElementById(eg.value + '-grammar').textContent, | ||
input.textContent = document.getElementById(eg.value + '-input').textContent; | ||
dingus.run(); | ||
}, | ||
} | ||
|
||
const firstExample = examples[0] | ||
|
||
window.load = () => { | ||
const selected = document.getElementById<HTMLSelectElement>('examples').value | ||
const option = document.getElementById(`option-${selected}`) | ||
const grammar = option.dataset.grammar | ||
const input = option.dataset.input | ||
document.getElementById('grammar').textContent = grammar; | ||
document.getElementById('input').textContent = input; | ||
window.run() | ||
} | ||
|
||
window.run = () => { | ||
const grammar = document.getElementById('grammar') | ||
const parser = ppeg.compile(grammar.textContent) | ||
const input = document.getElementById('input') | ||
const parse = parser.parse(input.innerText) //textContent), | ||
const output = document.getElementById('output'); | ||
if (parse.ok) output.textContent = parse.show_ptree(); // TODO json? | ||
else output.textContent = parse.show_err(); | ||
} | ||
|
||
window.load() | ||
</script> | ||
|
||
<Layout> | ||
<Welcome /> | ||
</Layout> | ||
<style> | ||
.box { | ||
display: flex; | ||
flex-wrap: wrap; | ||
} | ||
|
||
.grammar, .input, .output { | ||
flex: auto; | ||
width: 400px; | ||
margin: 2px; | ||
border: thin solid gray; | ||
} | ||
|
||
.header { | ||
position: relative; | ||
top: 0; | ||
height: 20px; | ||
padding: 5px; | ||
border-bottom: thin solid gray; | ||
background: whitesmoke; | ||
} | ||
|
||
.header > button { | ||
float: right; | ||
} | ||
|
||
.header > .examples { | ||
float: right; | ||
} | ||
|
||
#grammar, #input, #output { | ||
position: relative; | ||
height: 250px; | ||
font-family: "Courier Line Draw", "Courier Prime", "Courier New", monospace; | ||
white-space: pre-wrap; | ||
margin: 2px; | ||
padding: 5px; | ||
resize: both; | ||
overflow: auto; | ||
} | ||
</style> | ||
<h1>pPEG Dingus</h1> | ||
|
||
<div class='box'> | ||
<div class='grammar'> | ||
<div class='bag'> | ||
<div class='header'> | ||
<label for="grammar">Grammar</label> | ||
<span class='examples'> | ||
<label for="examples">Examples: </label> | ||
<select name="examples" id="examples" onchange="load()"> | ||
{examples.map(({title, grammar, input}) => | ||
<option id={`option-${title}`} value={title} data-grammar={grammar} data-input={input}>{title}</option>)} | ||
</select> | ||
</span> | ||
</div> | ||
<div id='grammar' contenteditable='true'></div> | ||
</div> | ||
</div> | ||
<div class='input'> | ||
<div class='bag'> | ||
<div class='header'> | ||
<label for="input">Input</label> | ||
<button onclick="run()">Parse..</button> | ||
</div> | ||
<div id='input' contenteditable='true'></div> | ||
</div> | ||
</div> | ||
<div class='output'> | ||
<div class='bag'> | ||
<div class='header'>Parse Tree</div> | ||
<div id='output'></div> | ||
</div> | ||
</div> | ||
</div> | ||
<div>Copyright 2024</div> | ||
</Layout> |