-------------------------------------------------------------------------------- -- Copyright (c) 2006-2013 Fabien Fleutot and others. -- -- All rights reserved. -- -- This program and the accompanying materials are made available -- under the terms of the Eclipse Public License v1.0 which -- accompanies this distribution, and is available at -- http://www.eclipse.org/legal/epl-v10.html -- -- This program and the accompanying materials are also made available -- under the terms of the MIT public license which accompanies this -- distribution, and is available at http://www.lua.org/license.html -- -- Contributors: -- Fabien Fleutot - API and implementation -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- -- Exported API: -- * [M.table_bracket_field()] -- * [M.table_field()] -- * [M.table_content()] -- * [M.table()] -- -- KNOWN BUG: doesn't handle final ";" or "," before final "}" -- -------------------------------------------------------------------------------- local gg = require 'metalua.grammar.generator' return function(M) M.table = { } local _table = gg.future(M.table) local _expr = gg.future(M).expr -------------------------------------------------------------------------------- -- `[key] = value` table field definition -------------------------------------------------------------------------------- M.table.bracket_pair = gg.sequence{ "[", _expr, "]", "=", _expr, builder = "Pair" } -------------------------------------------------------------------------------- -- table element parser: list value, `id = value` pair or `[value] = value` pair. -------------------------------------------------------------------------------- function M.table.element (lx) if lx :is_keyword (lx :peek(), "[") then return M.table.bracket_pair(lx) end local e = M.expr (lx) if not lx :is_keyword (lx :peek(), "=") then return e end lx :next(); -- skip the "=" local ok, key = pcall(M.id2string, e) -- will fail on non-identifiers if not ok then return gg.parse_error (lx, "Identifier expected.") end local val = M.expr(lx) local r = { tag="Pair", key, val } r.lineinfo = { first = key.lineinfo.first, last = val.lineinfo.last } return r end ----------------------------------------------------------------------------- -- table constructor, without enclosing braces; returns a full table object ----------------------------------------------------------------------------- M.table.content = gg.list { -- eta expansion to allow patching the element definition primary = _table.element, separators = { ",", ";" }, terminators = "}", builder = "Table" } -------------------------------------------------------------------------------- -- complete table constructor including [{...}] -------------------------------------------------------------------------------- -- TODO beware, stat and expr use only table.content, this can't be patched. M.table.table = gg.sequence{ "{", _table.content, "}", builder = unpack } return M end