It was thus said that the Great joy mondal once stated:

> Hi !

>

> This is the first time posting to a mailing list so I hope I do not get it

> wrong.

>

> I have trying to understand LPEG to help me build a full programming

> language, I really like moonscript and want to build something similar, I

> have a very basic question involving LPEG.

>

>

https://gist.github.com/randrews/5eab368f35ab8e774433#gistcomment-2692302>

> (Posting it in email would make it harder to read due to not having

> markdown support.)

>

> Are there other good resources like playwithlua.com for the specific

> purpose of building programming languages or would Andrew's series (Part

> 1,2,3,4) be enough.

You can read these two mailing list threads that go into LPeg:

http://lua-users.org/lists/lua-l/2017-10/msg00106.html http://lua-users.org/lists/lua-l/2018-01/msg00298.html There's also several Lua modules I wrote that use LPeg:

http://lua-users.org/lists/lua-l/2017-10/msg00126.html As for the particular issue you are having, it appears you want to parse

text like:

3 * -foo + 2

Yes, LPeg can do this. Sorry to do this, but I'm about to dump some LPeg.

This is from an assembler I wrote [1] that does deal with identifiers in

expressions.

local function knownvalue(n)

return { value = n % 65536 , unknownpass1 = false , defined = true }

end

local WS = S" \t"^1

local BIN = R"01"

local OCT = R"07"

local DEC = R"09"

local HEX = R("09","AF","af")

local OPAREN = P"(" * WS^-1

local CPAREN = P")" * WS^-1

local COMMA = WS^-1 * P"," * WS^-1

local value_bin = BIN^1 / function(c) return tonumber(c, 2) end

local value_oct = OCT^1 / function(c) return tonumber(c, 8) end

local value_dec = (S"+-"^-1 * DEC^1) / function(c) return tonumber(c,10) end

local value_hex = HEX^1 / function(c) return tonumber(c,16) end

local value_id = (id * Carg(1))

/ function(name,info)

if not info.symbols[name] then

info.symbols[name] = {}

info.symbols[name].type = 'undef'

info.symbols[name].value = 0

info.symbols[name].linenum = 0

info.symbols[name].unknownpass1 = true

end

return {

value = info.symbols[name].value,

unknownpass1 = info.symbols[name].unknownpass1,

defined = info.symbols[name].type ~= 'undef',

}

end

local value = P"$" * value_hex / knownvalue

+ P"&" * value_oct / knownvalue

+ P"%" * value_bin / knownvalue

+ value_dec / knownvalue

+ P"*" * Carg(1) / function(info) return knownvalue(info.PC) end

+ value_id

+ P"-" * value_id / function(v) v.value = -v.value return v end

+ P"~" * value_id / function(v) v.value = -v.value - 1 return v end

+ P"'" * C(1) / function(c) return

knownvalue(string.byte(c)) end

local term_op = C(S"+-") * WS^-1

local factor_op = C(S "*/") * WS^-1

local function eval(v1,op,v2)

if op == '+' then v1.value = v1.value + v2.value

elseif op == '-' then v1.value = v1.value - v2.value

elseif op == '*' then v1.value = v1.value * v2.value

elseif op == '/' then v1.value = v1.value / v2.value end

v1.unknownpass1 = v1.unknownpass1 or v2.unknownpass1

v1.defined = v1.defined and v2.defined

v1.value = v1.value % 65536

return v1

end

local expr = P {

"exp",

exp = Cf(V"term" * Cg(term_op * V"term" )^0,eval),

term = Cf(V"factor" * Cg(factor_op * V"factor")^0,eval),

factor = value * WS^-1

+ OPAREN * V"exp" * CPAREN

}

Start at the bottom with "expr" and work your way back up. The code is

expecting to be called like

symbol_table = { ... }

result = parser:match(input,1,symbol_table)

The key part is the 'value' production, but I'm including the full bit for

context (and remember this is part of an assembler so keep that in mind).

-spc (It's a two-pass assembler by the way ... )

[1] A Motorola 6809 Assembler in case anyone cares.