C Header File Parser in Lua Using Clang AST. Pallene, the statically typed sister language of Lua requires a Foreign Function Interface (FFI) to C. As a starting point, there is a need to create a library in Lua that can parse C header files and incorporate a functionality so as to represent C declarations in Lua. Unlike strings in JavaScript, Lua strings are not Unicode strings, but bytestrings (sequences of 8-bit values); likewise, implementations of Lua parse the source code as a sequence of octets. However, the input to this parser is a JavaScript string, i.e. A sequence of 16-bit code units (not necessarily well-formed UTF-16). Lua-cURL Lua-cURL is aiming for a full-fledged libcurl binding (easy/multi/share interface) to the functionality of Lua Download as.zip Download as.tar.gz View on GitHub.
Install
Htmlparser is a listed LuaRock. Install using LuaRocks: luarocks install htmlparser
Dependencies
C Lua Parser Game
Htmlparser depends on Lua 5.2, and on the 'set' LuaRock, which is installed along automatically. To be able to run the tests, lunitx also comes along as a LuaRock
Usage
Start off with
Then, parse some html:
The input to parse may be the contents of a complete html document, or any valid html snippet, as long as all tags are correctly opened and closed.Now, find specific contained elements by selecting:
Or in shorthand:
This wil return a list of elements, all of which are of the same type as the root element, and thus support selecting as well, if ever needed:
The root element is a container for the top level elements in the parsed text, i.e. the <html>
element in a parsed html document would be a child of the returned root element.
Selectors
Supported selectors are a subset of jQuery's selectors:
'*'
all contained elements'element'
elements with the given tagname'#id'
elements with the given id attribute value'.class'
elements with the given classname in the class attribute'[attribute]'
elements with an attribute of the given name'[attribute='value']'
equals: elements with the given value for the given attribute'[attribute!='value']'
not equals: elements without the given attribute, or having the attribute, but with a different value'[attribute|='value']'
prefix: attribute's value is given value, or starts with given value, followed by a hyphen (-
)'[attribute*='value']'
contains: attribute's value contains given value'[attribute~='value']'
word: attribute's value is a space-separated token, where one of the tokens is the given value'[attribute^='value']'
starts with: attribute's value starts with given value'[attribute$='value']'
ends with: attribute's value ends with given value':not(selectorstring)'
elements not selected by given selector string'ancestor descendant'
elements selected by thedescendant
selector string, that are a descendant of any element selected by theancestor
selector string'parent > child'
elements selected by thechild
selector string, that are a child element of any element selected by theparent
selector string
Selectors can be combined; e.g. '.class:not([attribute]) element.class'
Element type
All tree elements provide, apart from :select
and ()
, the following accessors:
Basic
.name
the element's tagname.attributes
a table with keys and values for the element's attributes;{}
if none.id
the value of the element's id attribute;nil
if not present.classes
an array with the classes listed in element's class attribute;{}
if none:getcontent()
the raw text between the opening and closing tags of the element;'
if none.nodes
an array with the element's child elements,{}
if none.parent
the element that contains this element;root.parent
isnil
Other
.index
sequence number of elements in order of appearance; root index is0
:gettext()
the complete element text, starting with'<tagname'
and ending with'/>'
or'</tagname>'
.level
how deep the element is in the tree; root level is0
.root
the root element of the tree;root.root
isroot
.deepernodes
a Set containing all elements in the tree beneath this element, including this element's.nodes
;{}
if none.deeperelements
a table with a key for each distinct tagname in.deepernodes
, containing a Set of all deeper element nodes with that name;{}
if none.deeperattributes
as.deeperelements
, but keyed on attribute name.deeperids
as.deeperelements
, but keyed on id value.deeperclasses
as.deeperelements
, but keyed on class name
Limitations
- Attribute values in selector strings cannot contain any spaces
- The spaces before and after the
>
in aparent > child
relation are mandatory <!
elements (including doctype, comments, and CDATA) are not parsed; markup within CDATA is not escaped- Textnodes are no separate tree elements; in
local root = htmlparser.parse('<p>line1<br />line2</p>')
,root.nodes[1]:getcontent()
is'line1<br />line2'
, whileroot.nodes[1].nodes[1].name
is'br'
- No start or end tags are implied when omitted. Only the void elements should not have an end tag
- No validation is done for tag or attribute names or nesting of element types. The list of void elements is in fact the only part specific to HTML
Examples
See ./doc/sample.lua
Tests
See ./tst/init.lua
License
LGPL+; see ./doc/LICENSE
A Lua parser written in JavaScript, for my bachelor's thesis at Arcada.
Installation
Install through bower install luaparse
or npm install luaparse
.
Usage
CommonJS
AMD
Browser
Parser Interface
Basic usage:
The output of the parser is an Abstract Syntax Tree (AST) formatted in JSON.
The available options are:
wait: false
Explicitly tell the parser when the input ends.comments: true
Store comments as an array in the chunk object.scope: false
Track identifier scopes.locations: false
Store location information on each syntax node.ranges: false
Store the start and end character locations on each syntaxnode.onCreateNode: null
A callback which will be invoked when a syntax nodehas been completed. The node which has been created will be passed as theonly parameter.onCreateScope: null
A callback which will be invoked when a new scope iscreated.onDestroyScope: null
A callback which will be invoked when the currentscope is destroyed.
The default options are also exposed through luaparse.defaultOptions
wherethey can be overriden globally.
There is a second interface which might be preferable when using the wait
option.
This would be identical to:
AST format
If the following code is executed:
then the returned value will be:
Custom AST
The default AST structure is somewhat inspired by the Mozilla Parser API butcan easily be overriden to customize the structure or to inject custom logic.
luaparse.ast
is an object containing all functions used to create the AST, ifyou for example wanted to trigger an event on node creations you could use thefollowing:
this is only an example to illustrate what is possible and this particularexample might not suit your needs as the end location of the node has not beendetermined yet. If you desire events you should use the onCreateNode
callbackinstead).
Lexer
The lexer used by luaparse can be used independently of the recursive descentparser. The lex function is exposed as luaparse.lex()
and it will return thenext token up until EOF
is reached.
Each token consists of:
type
expressed as an enum flag which can be matched withluaparse.tokenTypes
.value
line
,lineStart
range
can be used to slice out raw values, eg.foo = 'bar'
will return aStringLiteral
token with the valuebar
. Slicing out the range on the otherhand will return'bar'
.
Examples
Have a look in the examples directoryof the repository for some code examples or check them out live.
luaparse(1)
The luaparse
executable can be used in your shell by installing luaparse
globally using npm:
Example usage
Support
Has been tested in at least IE6+, Firefox 3+, Safari 4+, Chrome 10+, Opera 10+,Node 0.4.0+, RingoJS 0.8-0.9, Narwhal 0.3.2, Rhino 1.7R4-1.7R5, Nashorn 1.8.0.
Quality Assurance
TL;DR simply run make qa
. This will run all quality assurance scripts butassumes you have it set up correctly.
Begin by cloning the repository and installing the development dependencieswith npm install
. To test AMD loading for browsers you should run bowerinstall
which will download RequireJS.
The luaparse test suite uses testem as atest runner, and because of this it's very easy to run the tests usingdifferent javascript engines or even on locally installed browsers. Currentlythe default runner uses PhantomJS and node so whenusing make test
or npm test
you should have PhantomJS installed.
Test runners
make test
uses PhantomJS and node.make testem-engines
uses PhantomJS, node, narwhal, ringo, rhino and rhino1.7R5. This requires that you have the engines installed.make test-node
uses a custom command line reporter to make the outputeasier on the eyes while practicing TDD.- By installing
testem
globally you can also run the tests in a locallyinstalled browser.
Other quality assurance measures
- You can check the function complexity using complexity-reportusing
make complexity-analysis
- Running
make coverage
will generate the coverage report.To simply check that all code has coverage you can runmake coverage-analysis
. make lint
,make benchmark
,make profile
.
Documentation
By running make docs
all documentationwill be generated.
Projects using luaparse
C Lua Parser Roblox
- luamin, a Lua minifier written by Mathias Bynens.
- Ace, an online code editor.
C Lua Parser Online
Acknowledgements
- Initial tests are scaffolded from yueliang and then manually checked for error.
- Much of the code is based on LuaMinify, the Lua source and Esprima. All awesome projects.
License
Lua C Parser
MIT