Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - LuaDist/epeg: Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees. · GitHub
Skip to content
This repository was archived by the owner on Nov 20, 2020. It is now read-only.

Repository files navigation

Introduction
============
Epeg is a library to read PEGs from textfiles and apply them to input to create
abstract syntax trees.
Features:
- The complete PEG can be stored in a single plain textfile.
- You define in the PEG itself how the AST should look and what input you
want to store in the nodes.
- You can print parsing errors for malformed input.
- You can print warnings for input which is valid, but deprecated/
dangerous/... .
- You can call functions to implement actions or extended tests.
- You can dump the grammar into a lua-table instead of reading the PEG
everytime from textfile, which enhances performance.
- The AST stores for every node at which position/row/column in the inputstream
it got created.
- Classes use lua syntax for patternmatching (for example [^%l] or [%L])
- Lua escapesequences get converted into their binary counterparts while
reading the PEG (only single characters).
- Checks for possible left infinite recursion while parsing the PEG.
Note: If you are only interested in running actions while parsing input, you
should consider lpeg instead, because it is much better for this kind of work.
Usage
=====
- store the PEG in a textfile
- use epeg = dofile("epeg.lua") to include the library (not a fancy lua module)
- use epeg.read_grammar("example.epeg") to get the grammar
- use epeg.parse_text(grammar, text) to parse some text and get an AST
- use epeg.dump_grammar(grammar, name, filename) to dump the grammar as
lua table and retrieve it later for better runtime performance, instead of
reading the PEG from textfile everytime.
Files
=====
epeg.lua - the library
epeg.epeg - the PEG for PEG itself (used for development)
epegscanner.lua - use it to dump the grammar from epeg.epeg
(result stored in r1.lua)
TODO - tasks planned/possible
README - this file
COPYING - copyright notices
Handling Errors and Warnings
============================
If you want to handle errors and warnings, just append
'error ("message")' or 'warning ("message")' aftern a pattern. You can't
append both (yet.):
FunctionName <- ([a-z][A-Z]*) error ("Expected at least one letter.")
Pragma <- 'pragma' [%s] warning ("The use of #pragma is deprecated.")
If a pattern with an error attribute fails, the parser aborts and prints the
error message.
You can't append both error/warning to a node.
Grabbing Nodes and Input
========================
Nodes are represented by tables in lua. The following indexes are used for
every node and cannot be used as nodenames:
position/
row/
column: stores the position where the node in the input stream
got created.
parent: a backlink to the parent node or nil if no parentnode exists.
pindex: index of the node in it's parent.
Thus node.parent[node.pindex] == node.
string: grabbed input.
'< Pattern >' grabs the matched pattern and appends the result in the actual
node to node.string (initialized with ""). If Pattern fails, nothing gets
stored. You can nest this construct.
'<NodeName: Pattern >' creates a new node with the name NodeName as a childnode
of the actual node. If a childnode with the same name already exists, the
operation fails and the parser stops with an errormessage. For Pattern the
actual node becomes the newly created node.
'<NodeName::"String">' is similar to '<:NodeName: Pattern>', but stores a
fixed String as content of the node in node.string.
'<: Pattern >' creates a node with no name. The name is set to the lowest free
positive integer in the parentnode starting with 1. This is useful to create
lists of nodes.
'<::"String">' is similar to '<: Pattern>' but creates a node with a fixed
string as content.
Calling Functions
=================
You can call functions from the PEG to handle certain situations. The function
gets as first argument the parser with the actual position (position/row/column)
and as second argument the actual node.
To add a functioncall use {: FunctionName }. If you want a function to check
for a condition, add a &/! in front of it:
&{: check_condition }
Standard PEG constructs
=======================
(You should read peg-popl04 for a thorough understanding)
Examples:
rule declaration: Rulename <- ...
class: [a-zA-Z_.]
choice: "hello" / "goodbye"
subpatterns: (!r1 r2* / r3)+ / (r4)* r5
Library
=======
You can use the following functions in the library:
epeg.read_grammar(filename)
Reads a PEG from file filename and returns the grammar. Returns false and
prints error messages to stdout if fails.
epeg.parse_text(grammar, text)
Parses the text using grammar. Grammar has to be a valid grammar created by
epeg.read_grammar or stored by epeg.dump_grammar. Returns the AST if successful,
else false. Prints all messages to stdout.
epeg.dump_grammar(grammar, name, filename)
Dumps the grammar as lua-table in file filename with the name name. if name
is not a string, it will use 'return {...' instead of 'name = {...'. If
filename is not given the output will go to stdout. Prints all messages to
stdout. If you want to use the dumped grammar, just use the table as the
grammar argument with parse_text next time.
All other functions are either for debugging purposes or get called by these 3
functions.

About

Epeg is a library to read PEGs from textfiles and apply them to input to create abstract syntax trees.

Resources

Stars

1 star

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages