Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Special pages
Random page
Wiki Discord
Contents
Neighbors
Galaxy
> Hexia
> Norvan
> Pashah
> Taffeh
Creatures
> Insects
> Fishes
> Shore-Dwellers
Items
> Dishes
> Furniture
Game Systems
> Dress Up
> Luca Arbor
> Loomix Footprints
> Loomix Vehicle Services
> Loomix Homes
Search
Search
Appearance
Log in
Personal tools
Log in
Editing
Module
:
Lexer
Module
Discussion
English
Read
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit source
View history
General
What links here
Related changes
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- <nowiki> -- Copyright (c) 2018 LoganDark -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in all -- copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. -- <nowiki> --- Lexer for Lua source code written in pure Lua. -- @script lexer -- @license MIT -- @author [[github:LoganDark|LoganDark]] -- @param {string} text Lua source code to lex. -- @return {string} Table of line arrays containing lexemes. --- Mapper for individual token list string. -- @param {string} src List of characters or keywords to map. -- @param[opt] {table} list Table to extend by reference. -- @return {{char=true,...}}, map -- @local local function lookupify(src, list) list = list or {} if type(src) == 'string' then for i = 1, src:len() do list[src:sub(i, i)] = true end elseif type(src) == 'table' then for i = 1, #src do list[src[i]] = true end end return list end --- Base identifier character set. -- @variable {string} base_ident local base_ident = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_' --- Base identifier character set. -- @variable {string} base_digits local base_digits = '0123456789' --- Base identifier character set. -- @variable {string} base_operators local base_operators = '+-*/^%#' --- Map of Lua character patterns. -- @table chars -- @field {table} whitespace Boolean map of whitespace -- tokens. -- @field {table} validEscapes Boolean map of valid escape -- characters. -- @field {table} ident Boolean map of valid identifier -- characters. -- @field {table} symbols Boolean map of valid symbol and -- operator characters. -- @local local chars = { whitespace = lookupify(' \n\t\r'), validEscapes = lookupify('abfnrtv"\'\\'), ident = lookupify( base_ident .. base_digits, { start = lookupify(base_ident), } ), digits = lookupify( base_digits, { hex = lookupify(base_digits .. 'abcdefABCDEF') } ), symbols = lookupify( base_operators .. ',{}[]();.:', { equality = lookupify('~=><'), operators = lookupify(base_operators) } ) } --- List of Lua keywords. -- @table keywords -- @field structure Boolean map of structure keywords. -- @field values Boolean map of primitive keywords. local keywords = { structure = lookupify({ 'and', 'break', 'do', 'else', 'elseif', 'end', 'for', 'function', 'goto', 'if', 'in', 'local', 'not', 'or', 'repeat', 'return', 'then', 'until', 'while' }), values = lookupify({ 'true', 'false', 'nil' }) } -- Lexer function export. return function(text) local pos = 1 local start = 1 local buffer = {} local lines = {} local function look(delta) delta = pos + (delta or 0) return text:sub(delta, delta) end local function get() pos = pos + 1 return look(-1) end local function getDataLevel() local num = 0 while look(num) == '=' do num = num + 1 end if look(num) == '[' then pos = pos + num + 1 return num end end local function getCurrentTokenText() return text:sub(start, pos - 1) end local currentLineLength = 0 local lineoffset = 0 local function pushToken(type, text) text = text or getCurrentTokenText() local tk = buffer[#buffer] if not tk or tk.type ~= type then tk = { type = type, data = text, posFirst = start - lineoffset, posLast = pos - 1 - lineoffset } if tk.data ~= '' then buffer[#buffer + 1] = tk end else tk.data = tk.data .. text tk.posLast = tk.posLast + text:len() end currentLineLength = currentLineLength + text:len() start = pos return tk end local function newline() lines[#lines + 1] = buffer buffer = {} get() pushToken('newline') buffer[1] = nil lineoffset = lineoffset + currentLineLength currentLineLength = 0 end local function getData(level, type) while true do local char = get() if char == '' then return elseif char == '\n' then pos = pos - 1 pushToken(type) newline() elseif char == ']' then local valid = true for i = 1, level do if look() == '=' then pos = pos + 1 else valid = false break end end if valid and look() == ']' then pos = pos - level - 1 return end end end end local function chompWhitespace() while true do local char = look() if char == '\n' then pushToken('whitespace') newline() elseif chars.whitespace[char] then pos = pos + 1 else break end end pushToken('whitespace') end while true do chompWhitespace() local char = get() if char == '' then break elseif char == '-' and look() == '-' then pos = pos + 1 if look() == '[' then pos = pos + 1 local level = getDataLevel() if level then getData(level, 'comment') pos = pos + level + 2 pushToken('comment') else while true do local char2 = get() if char2 == '' or char2 == '\n' then pos = pos - 1 pushToken('comment') if char2 == '\n' then newline() end break end end end else while true do local char2 = get() if char2 == '' or char2 == '\n' then pos = pos - 1 pushToken('comment') if char2 == '\n' then newline() end break end end end pushToken('comment') elseif char == '\'' or char == '"' then pushToken('string_start') while true do local char2 = get() if char2 == '\\' then pos = pos - 1 pushToken('string') get() local char3 = get() if chars.digits[char3] then for i = 1, 2 do if chars.digits[look()] then pos = pos + 1 end end elseif char3 == 'x' then if chars.digits.hex[look()] and chars.digits.hex[look(1)] then pos = pos + 2 else pushToken('unidentified') end elseif char3 == '\n' then pos = pos - 1 pushToken('escape') newline() elseif not chars.validEscapes[char3] then pushToken('unidentified') end pushToken('escape') elseif char2 == '\n' then pos = pos - 1 pushToken('string') newline() break elseif char2 == char or char2 == '' then pos = pos - 1 pushToken('string') get() break end end pushToken('string_end') elseif chars.ident.start[char] then while chars.ident[look()] do pos = pos + 1 end local word = getCurrentTokenText() if keywords.structure[word] then pushToken('keyword') elseif keywords.values[word] then pushToken('value') else pushToken('ident') end elseif chars.digits[char] or (char == '.' and chars.digits[look()]) then if char == '0' and look() == 'x' then pos = pos + 1 while chars.digits.hex[look()] do pos = pos + 1 end else while chars.digits[look()] do pos = pos + 1 end if look() == '.' then pos = pos + 1 while chars.digits[look()] do pos = pos + 1 end end if look():lower() == 'e' then pos = pos + 1 if look() == '-' then pos = pos + 1 end while chars.digits[look()] do pos = pos + 1 end end end pushToken('number') elseif char == '[' then local level = getDataLevel() if level then pushToken('string_start') getData(level, 'string') pushToken('string') pos = pos + level + 2 pushToken('string_end') else pushToken('symbol') end elseif char == '.' then if look() == '.' then pos = pos + 1 if look() == '.' then pos = pos + 1 end end if getCurrentTokenText():len() == 3 then pushToken('vararg') else pushToken('symbol') end elseif char == ':' and look() == ':' then get() pushToken('label_start') chompWhitespace() if chars.ident.start[look()] then get() while chars.ident[look()] do get() end pushToken('label') chompWhitespace() if look() == ':' and look(1) == ':' then get() get() pushToken('label_end') end end elseif chars.symbols.equality[char] then if look() == '=' then pos = pos + 1 end pushToken('operator') elseif chars.symbols[char] then if chars.symbols.operators[char] then pushToken('operator') else pushToken('symbol') end else pushToken('unidentified') end end lines[#lines + 1] = buffer return lines end
Summary:
Please note that all contributions to The Petit Planet Wiki are considered to be released under the Creative Commons Attribution-ShareAlike (see
Petit Planet Wiki:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Preview page with this template
Below are commonly used wikitext from
MediaWiki:Edittools
. Click on any to insert them in the edit box.
File Pages
==Summary==
==Licensing==
{{Fairuse}}
{{File|}}
Dynamic Page List
¦
²
«
»
²{¦}²
«»
«/»
«!----»
Array in DPL
¹
^2{
}^2
^2{¹}^2
Parser Functions
{{#if:||}}
{{#if:<condition>|<result if true>|<result if false>}}
{{#ifeq:|||}}
{{#ifeq:<text1>|<text2>|<result if text1=text2>|<result if text1≠text2>}}
{{#expr:}}
{{#expr:<mathematical expression>}}
{{#switch:||#default=}}
{{#switch:<text1>|<text2>=<result if text1=text2>|<text3>=<result if text1=text3>|#default=<result if no valid match>}}
{{#replace:||}}
{{#replace:<text1>|<plain text to find in text1>|<plain text to insert in place of the text found>}}
{{#titleparts:}}
{{#replace:<page name>}}
{{#tag:|}}
{{#tag:<name of html tag>|<content inside html tag>}}
Markup
{{}}
|
[]
[[]]
[[Category:]]
#REDIRECT [[]] [[Category:Redirect Pages]]
<code></code>
<includeonly></includeonly>
<noinclude></noinclude>
<nowiki></nowiki>
<!---->
<br>
§
Notices
{{Stub|}}
{{Stub Dialogue}}
{{Upcoming}}
{{Under Construction}}
{{Placeholder|}}
Magic Words
{{!}}
{{formatnum:}}
{{lc:}}
{{uc:}}
{{PAGENAME}}
{{FULLPAGENAME}}
{{ROOTPAGENAME}}
{{BASEPAGENAME}}
{{SUBPAGENAME}}
{{DISPLAYTITLE:|noreplace}}
__TOC__
__NOTOC__
__EXPECTUNUSEDCATEGORY__
__HIDDENCAT__
HTML Entities
—
,
­
Pages included on this page:
Template:Documentation/Header
(
edit
)
Template:Documentation/styles.css
(
edit
)
Template:F
(
edit
)
Template:M
(
edit
)
Template:TOC Right
(
edit
)
Module:Arguments
(
edit
)
Module:Arguments/i18n
(
edit
)
Module:Common/i18n
(
edit
)
Module:Config
(
edit
)
Module:Documentation
(
edit
)
Module:Documentation/config
(
edit
)
Module:Documentation/i18n
(
edit
)
Module:Entrypoint
(
edit
)
Module:Exists
(
edit
)
Module:Fallbacklist
(
edit
)
Module:Feature
(
edit
)
Module:Formatting
(
edit
)
Module:I18n
(
edit
)
Module:Languages
(
edit
)
Module:Lexer/doc
(
edit
)
Module:TableTools
(
edit
)
Module:Yesno
(
edit
)
This page is a member of 2 hidden categories:
Category:Pages using DynamicPageList4 parser function
Category:Pages using DynamicPageList4
Search
Search
Editing
Module
:
Lexer
Add topic