Skip to content

Instantly share code, notes, and snippets.

@zoon
Created April 26, 2010 10:28
Show Gist options
  • Save zoon/379183 to your computer and use it in GitHub Desktop.
Save zoon/379183 to your computer and use it in GitHub Desktop.
[[
01234567890123456789012345678901234567890123456789012345678901234567890123456789
]]
-- NOTE: requires 'LPEG' module
local re = require're'
local assert = assert
local min, max = math.min, math.max
-- PEG Grammar 1:
local GG1 = [[
osm <- '<?xml' (!'?' .)+ '?>' <xml> <ws>
xml <- <node>* -> {}
node <- <ws> '<' {:tag: <name> :} <param>*
<ws> ('/>' / '>' <xml> <ws> '</' <ws> =tag <ws> '>')
param <- (<ws> <name> '=' <string> <ws>) -> processData
string <- '"' { (!'"' .)* } '"'
name <- { %w+ }
ws <- %s*
]]
-- PEG Grammar 2:
local GG2 = [[
osm <- ((<ws> '<' (<node> / <tag>))*) <ws>
node <- 'node' <param>* <ws> <endnode>
endnode <- '/>'
/ (!'</node>' .)* '</node>'
param <- (<ws> <name> '=' <string> <ws>) -> processData
tag <- (!'>' .)* '>'
string <- '"' { (!'"' .)* } '"'
name <- { %w+ }
ws <- %s*
]]
-- TEST:
local Bounds = {
reset = function(self)
assert(self)
self.minlat = 1E9
self.maxlat = -1E9
self.minlon = 1E9
self.maxlon = -1E9
return self
end
}
local function processData(key,val)
if key == 'lat' then
local lat = assert(tonumber(val))
Bounds.minlat = min(lat,Bounds.minlat)
Bounds.maxlat = max(lat,Bounds.maxlat)
elseif key == 'lon' then
local lon = assert(tonumber(val))
Bounds.minlon = min(lon,Bounds.minlon)
Bounds.maxlon = max(lon,Bounds.maxlon)
end
end
local Parser1 = re.compile(GG1,{processData = processData})
local Parser2 = re.compile(GG2,{processData = processData})
-- http://downloads.cloudmade.com/asia/singapore/singapore.osm.bz2
local singapore = assert(io.open("singapore.osm"):read('*a'))
-- ------------
Bounds:reset()
local t1 = os.clock()
local result = re.match(singapore,Parser1)
print('Parser1',os.clock()-t1,'sec')
print("Bounds.minlat", Bounds.minlat)
print("Bounds.maxlat", Bounds.maxlat)
print("Bounds.minlon", Bounds.minlon)
print("Bounds.maxlon", Bounds.maxlon)
-- ------------
-- ------------
Bounds:reset()
local t1 = os.clock()
local result = re.match(singapore,Parser2)
print('Parser2',os.clock()-t1,'sec')
print("Bounds.minlat", Bounds.minlat)
print("Bounds.maxlat", Bounds.maxlat)
print("Bounds.minlon", Bounds.minlon)
print("Bounds.maxlon", Bounds.maxlon)
-- ------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment