Giter Site home page Giter Site logo

lua-parser's Issues

help

I have questions.. and the ast is mind blowing to loop 😂

in string we have this

[09:01 ob ]$ ob
{ Set{ { Id "main" }, { Function{ { }, { Set{ { Id "select" }, { Call{ Index{ Id "gg", String "choice" }, Table{ String "test1", String "test2" } } } }, If{ Op{ "eq", Id "select", Number "1" }, { Call{ Index{ Id "test", String "show" } } } }, If{ Op{ "eq", Id "select", Number "2" }, { Call{ Index{ Id "test", String "show2" } } } } } } } }, Set{ { Id "a" }, { Number "1" } }, Set{ { Id "b" }, { String "3(£+£+£+£+" } }, Set{ { Id "test" }, { Table{ Pair{ String "show", Function{ { }, { Call{ Index{ Id "gg", String "alert" }, String "find me" } } } }, Pair{ String "show2", Function{ { }, { Call{ Index{ Id "gg", String "alert" }, String "yay me" } } } } } } }, Call{ `Id "main" } }

and. i have this as table
``
{ { { { "main",
pos = 10,
tag = "Id"
} }, { { {}, { { { { "select",
pos = 21,
tag = "Id"
},
pos = 21,
tag = "VarList"
}, { { { { "gg",
pos = 30,
tag = "Id"
}, { "choice",
pos = 33,
tag = "String"
},
pos = 30,
tag = "Index"
}, { { "test1",
pos = 51,
tag = "String"
}, { "test2",
pos = 69,
tag = "String"
},
pos = 40,
tag = "Table"
},
pos = 30,
tag = "Call"
},
pos = 30,
tag = "ExpList"
},
pos = 21,
tag = "Set"
}, { { "eq", { "select",
pos = 91,
tag = "Id"
}, { 1,
pos = 101,
tag = "Number"
},
pos = 91,
tag = "Op"
}, { { { { "test",
pos = 108,
tag = "Id"
}, { "show",
pos = 113,
tag = "String"
},
pos = 108,
tag = "Index"
},
pos = 108,
tag = "Call"
},
pos = 108,
tag = "Block"
},
pos = 88,
tag = "If"
}, { { "eq", { "select",
pos = 131,
tag = "Id"
}, { 2,
pos = 141,
tag = "Number"
},
pos = 131,
tag = "Op"
}, { { { { "test",
pos = 148,
tag = "Id"
}, { "show2",
pos = 153,
tag = "String"
},
pos = 148,
tag = "Index"
},
pos = 148,
tag = "Call"
},
pos = 148,
tag = "Block"
},
pos = 128,
tag = "If"
},
pos = 21,
tag = "Block"
},
pos = 14,
tag = "Function"
} },
pos = 1,
tag = "Set"
}, { { { "a",
pos = 177,
tag = "Id"
},
pos = 177,
tag = "VarList"
}, { { 1,
pos = 181,
tag = "Number"
},
pos = 181,
tag = "ExpList"
},
pos = 177,
tag = "Set"
}, { { { "b",
pos = 187,
tag = "Id"
},
pos = 187,
tag = "VarList"
}, { { "3(£+£+£+£+",
pos = 191,
tag = "String"
},
pos = 191,
tag = "ExpList"
},
pos = 187,
tag = "Set"
}, { { { "test",
pos = 212,
tag = "Id"
},
pos = 212,
tag = "VarList"
}, { { { { "show",
pos = 229,
tag = "String"
}, { {}, { { { { "gg",
pos = 259,
tag = "Id"
}, { "alert",
pos = 262,
tag = "String"
},
pos = 259,
tag = "Index"
}, { "find me",
pos = 268,
tag = "String"
},
pos = 259,
tag = "Call"
},
pos = 259,
tag = "Block"
},
pos = 244,
tag = "Function"
},
pos = 229,
tag = "Pair"
}, { { "show2",
pos = 300,
tag = "String"
}, { {}, { { { { "gg",
pos = 331,
tag = "Id"
}, { "alert",
pos = 334,
tag = "String"
},
pos = 331,
tag = "Index"
}, { "yay me",
pos = 340,
tag = "String"
},
pos = 331,
tag = "Call"
},
pos = 331,
tag = "Block"
},
pos = 316,
tag = "Function"
},
pos = 300,
tag = "Pair"
},
pos = 219,
tag = "Table"
},
pos = 219,
tag = "ExpList"
},
pos = 212,
tag = "Set"
}, { { "main",
pos = 372,
tag = "Id"
},
pos = 372,
tag = "Call"
},
pos = 1,
tag = "Block"
}

``

how can i loop in all of this?
hmm I want to get all
functions name
variable names

the script looks like this

function main() select = gg.choice({ "test1", "test2" }) if select == 1 then test.show() end if select == 2 then test.show2() end end a = 1 b = "3(£+£+£+£+" test = { show = function() gg.alert("find me") end, show2 = function() gg.alert("yay me") end } main()

can't parse goto

lp = require 'lua-parser.parser'
lp.parse('::xx::; goto xxx')
parser.lua:75: bad argument #2 to 'format' (string expected, got nil)

<= and >= are scanned as the same token

Your example produces the same syntax tree for two very different code snippets

a=1>=4
a=1<=4

Bot produce

{ `Set{ { `Id "a" }, { `Op{ "le", `Number "1", `Number "4" } } } }

Problem may in lua-parser/parser.lua:binaryOp

Hi Andre, there may be something not right in lua-parser/parser.lua:binaryOp:

local function binaryOp (e1, op, e2)
  if not op then
    return e1
  end

  local node = { tag = "Op", pos = e1.pos, [1] = op, [2] = e1, [3] = e2 }

  if op == "ne" then
    node[1] = "eq"
    node = unaryOp("not", node)
  elseif op == "gt" then
    node[1], node[2], node[3] = "lt", e2, e1     --<-- problem
  elseif op == "ge" then
    node[1], node[2], node[3] = "le", e2, e1     --<-- problem
  end

  return node
end
$ cat t.lua
gl_f_ct = 0

function f()
    if gl_f_ct <= 0 then
        gl_f_ct=1
        return 1000
    end
    return -1000
end

print( f("1st call") > f("2nd call") ) --> in lua-parser's ast: lt f("2nd call") f("1st call")  | wrong
gl_f_ct = 0
print( f("1st call") < f("2nd call") ) --> in lua-parser's ast: lt f("1st call") f("2nd call")  | right

$ luajit -bl t.lua
-- BYTECODE -- t.lua:3-9
0001    GGET     0   0      ; "gl_f_ct"
0002    KSHORT   1   0
0003    ISGT     0   1
0004    JMP      0 => 0009
0005    KSHORT   0   1
0006    GSET     0   0      ; "gl_f_ct"
0007    KSHORT   0 1000
0008    RET1     0   2
0009 => KSHORT   0 -1000
0010    RET1     0   2

-- BYTECODE -- t.lua:0-15
0001    KSHORT   0   0
0002    GSET     0   0      ; "gl_f_ct"
0003    FNEW     0   1      ; t.lua:3
0004    GSET     0   2      ; "f"
0005    GGET     0   3      ; "print"
0006    GGET     1   2      ; "f"
0007    KSTR     2   4      ; "1st call"   <-- right
0008    CALL     1   2   2
0009    GGET     2   2      ; "f"
0010    KSTR     3   5      ; "2nd call"   <-- right
0011    CALL     2   2   2
0012    ISLT     2   1
0013    JMP      1 => 0016
0014    KPRI     1   1
0015    JMP      2 => 0017
0016 => KPRI     1   2
0017 => CALL     0   1   2
0018    KSHORT   0   0
0019    GSET     0   0      ; "gl_f_ct"
0020    GGET     0   3      ; "print"
0021    GGET     1   2      ; "f"
0022    KSTR     2   4      ; "1st call"  <-- right
0023    CALL     1   2   2
0024    GGET     2   2      ; "f"
0025    KSTR     3   5      ; "2nd call"  <-- right
0026    CALL     2   2   2
0027    ISLT     1   2
0028    JMP      1 => 0031
0029    KPRI     1   1
0030    JMP      2 => 0032
0031 => KPRI     1   2
0032 => CALL     0   1   2
0033    RET0     0   1

$ lua parse_str.lua 'print( f("1st call") > f("2nd call") ) ; print( f("1st call") < f("2nd call") )'
{
  [tag] = Block
  [pos] = 1
  [1] = {
    [tag] = Call
    [pos] = 1
    [1] = {
      [tag] = Id
      [pos] = 1
      [1] = print
    }
    [2] = {
      [tag] = Op
      [pos] = 8
      [1] = lt
      [2] = {
        [tag] = Call
        [pos] = 24
        [1] = {
          [tag] = Id
          [pos] = 24
          [1] = f
        }
        [2] = {
          [tag] = String
          [pos] = 26
          [1] = 2nd call     <-- wrong
        }
      }
      [3] = {
        [tag] = Call
        [pos] = 8
        [1] = {
          [tag] = Id
          [pos] = 8
          [1] = f
        }
        [2] = {
          [tag] = String
          [pos] = 10
          [1] = 1st calll     <-- wrong
        }
      }
    }
  }
  [2] = {
    [tag] = Call
    [pos] = 42
    [1] = {
      [tag] = Id
      [pos] = 42
      [1] = print
    }
    [2] = {
      [tag] = Op
      [pos] = 49
      [1] = lt
      [2] = {
        [tag] = Call
        [pos] = 49
        [1] = {
          [tag] = Id
          [pos] = 49
          [1] = f
        }
        [2] = {
          [tag] = String
          [pos] = 51
          [1] = 1st calll     <-- right
        }
      }
      [3] = {
        [tag] = Call
        [pos] = 65
        [1] = {
          [tag] = Id
          [pos] = 65
          [1] = f
        }
        [2] = {
          [tag] = String
          [pos] = 67
          [1] = 2nd call    <-- right
        }
      }
    }
  }
}

I think the AST shouldn't consider too much about the constraints of latter IR phase. And there maybe two possible solutions:

  1. Add 'gt' & 'ge' to the opid (which is used in PR11).

  2. Use the mathematical transformation below to solve it lazily (but which would cause some more unnecessarily complexity):

( f1 > f2  ) == ( not ( f1 <= f2 ) )
( f1 >= f2  ) == ( not ( f1 < f2 ) )

Thanks a lot and all best :)

parsing error are not properly reported

Steps to reproduce

  1. create an empty directory in /tmp and cd into it.
  2. pip install hererocks
  3. hererocks . -r^ --lua=5.3
  4. ./bin/luarocks install lua-parser
  5. copy the code example in README as parse.lua:
local parser = require "lua-parser.parser"
local pp = require "lua-parser.pp"

if #arg ~= 1 then
    print("Usage: parse.lua <string>")
    os.exit(1)
end

local ast, error_msg = parser.parse(arg[1], "example.lua")
if not ast then
    print(error_msg)
    os.exit(1)
end

pp.print(ast)
os.exit(0)
  1. ./bin/lua parse.lua "for i=1, 10 do print(i)"

Expected behavior

example.lua:1:24: syntax error, expected 'end' to close the for loop

Actual behavior

./bin/lua: ./share/lua/5.3/lua-parser/parser.lua:478: attempt to get length of a number value (local 'sfail')
stack traceback:
	./share/lua/5.3/lua-parser/parser.lua:478: in function 'lua-parser.parser.parse'
	parse.lua:9: in main chunk
	[C]: in ?

Optional code context linked with ast node

I've faced a problem in reproducing original lua source code from AST. There is a pos field in AST node but is it possible to add optional code context? For example:
I have the following original code:

if a == 3 and b then end

and corresponding AST for it;

{ { { "and", { "eq", { "a",
          pos = 4,
          tag = "Id"
        }, { 3,
          pos = 9,
          tag = "Number"
        },
        pos = 4,
        tag = "Op"
      }, { "b",
        pos = 15,
        tag = "Id"
      },
      pos = 4,
      tag = "Op"
    }, {
      pos = 22,
      tag = "Block"
    },
    pos = 1,
    tag = "If"
  },
  pos = 1,
  tag = "Block"
}

I want to restore orig code for if condition body. On one hand I believe that I can do it via Breadth-first search on the AST, but some info can be missing: some binary comparation operators transformed in non-revertable AST such as >= & <=, etc. Lua comments are dropped and so on.

So as the result there is a bunch of questions:

  1. Is it possible to add some tag and parser for comments to reflect them in AST?
  2. Maybe we should preserve original code format in AST. I mean not combining commutative operators in same tags (comparation operators, constructions like not a == b, etc)
  3. Is it feasible to add original code context to AST node?
  4. Maybe optionally save whilespaces in AST? Can be useful for code structure (indentation based) linting / static analysis.

Problem in pp.dump

The command line below will simply throw an error if without this commit .

$cat parse.lua
local parser = require "lua-parser.parser"
local pp = require "lua-parser.pp"

if #arg ~= 1 then
    print("Usage: parse.lua <string>")
    os.exit(1)
end

local ast, error_msg = parser.parse(arg[1], "example.lua")
if not ast then
    print(error_msg)
    os.exit(1)
end

pp.dump(ast)
os.exit(0)

$ lua parse.lua "x=2;local function x() end"
lua: /usr/share/lua/5.1/lua-parser/pp.lua:314: bad argument #3 to 'format' (string expected, got nil)
stack traceback:
        [C]: in function 'format'
        /usr/share/lua/5.1/lua-parser/pp.lua:314: in function 'dump'
        /usr/share/lua/5.1/lua-parser/pp.lua:319: in function 'dump'
        /usr/share/lua/5.1/lua-parser/pp.lua:319: in function 'dump'
        parse_str.lua:54: in main chunk
        [C]: ?

Expected output after this commit:

{
  [tag] = Block
  [pos] = 1
  [1] = {
    [tag] = Set
    [pos] = 1
    [1] = {
      [tag] = VarList
      [pos] = 1
      [1] = {
        [tag] = Id
        [pos] = 1
        [1] = x
      }
    }
    [2] = {
      [tag] = ExpList
      [pos] = 3
      [1] = {
        [tag] = Number
        [pos] = 3
        [1] = 2
      }
    }
  }
  [2] = {
    [tag] = Localrec
    [pos] = 11
    [1] = {
      [1] = {
        [tag] = Id
        [pos] = 20
        [1] = x
      }
    }
    [2] = {
      [1] = {
        [tag] = Function
        [pos] = 21
        [1] = {
        }
        [2] = {
          [tag] = Block
          [pos] = 24
        }
      }
    }
  }
}

I don't know whether this is just a little implementation problem within pp.dump or actually due to the inconsistence of the AST which generated by the parser.

Thanks a lot and all best to you. lua-parser is a pretty cool project 👍

problem with fix_str() in parser.lua

When given the string
"\\a"
The fix_str() function will make this into
"\\\a"
Instead of the correct
"\a"

This is the same for all escaped characters. (\b,\n,\r ect.)

"attempt to get length of a number value (local 'sfail')" when parsing wrong syntax

Error

lua5.3: /usr/local/share/lua/5.3/lua-parser/parser.lua:478: attempt to get length of a number value (local 'sfail')
stack traceback:
    /usr/local/share/lua/5.3/lua-parser/parser.lua:478: in function 'lua-parser.parser.parse'
    <my code>
    [C]: in ?

Steps to reproduce

require 'luarocks.loader'
local parser = require 'lua-parser.parser'

local source = "while true do"
local ast, err = parser.parse(source, "sourcefile.lua")

Seems like this happens with any invalid syntax.

Versions

luarocks 3.0.4
lua-parser 1.0.0-1
LPegLabel 1.5.0-1
Lua 5.3.3

Additional info

This issue does not occur with lua-parser 0.1.1-1. The parse function returns normally and error message is sourcefile.lua:1:13: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'Name', 'goto', 'break', '::', 'local', 'function', 'repeat', 'for', 'do', 'while', 'if', ';'

All tests pass, but fail sometimes !

Hello,

I enjoyed by your lua-parser !
I started to testt it and it fail, because I'm on a quiet old debian with LPeg 0.10.
I decided to check with LuLPeg (LPeg 0.12).
All tests passed with lua5.1, luajit(5.1) and lua5.2 !

I discovered all tests pass... but sometimes it fail !
Always at the assert of the line 598.

I add some debug print and got different error message, but the most of time it raise the funny message syntax error, unexpected 'do', expecting 'do', ....

I only got failure with lua5.1 (not lua5.2)
EDIT: I also got the same error with luajit(2.0.3 compat 5.1))

The full logs :

tst2005/lua-parser$ while lua5.1 test.lua; do sleep 5;done                                                                                                                               
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
assert(r==e)    r:      string  test.lua:1:1: syntax error, unexpected 'while', expecting 'return', '(', 'Name', 'goto', 'break', '::', 'local', 'function', 'repeat', 'for', 'do', '[', 'if', ';'
        e:      { `While{ `Number "1", { `Break } } }
        string  s:
lua5.1: ERROR: assert fail at line ~598
stack traceback:
        [C]: in function 'error'
        test.lua:645: in main chunk
        [C]: ?
tst2005/lua-parser$ while lua5.1 test.lua; do sleep 5;done
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
assert(r==e)    r:      string  test.lua:1:9: syntax error, unexpected 'do', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
        e:      { `While{ `Number "1", { `Break } } }
        string  s:
lua5.1: ERROR: assert fail at line ~598
stack traceback:
        [C]: in function 'error'
        test.lua:645: in main chunk
        [C]: ?
tst2005/lua-parser$ while lua5.1 test.lua; do sleep 5;done
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
OK
> testing lexer...
> testing parser...
assert(r==e)    r:      string  test.lua:1:9: syntax error, unexpected 'do', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
        e:      { `While{ `Number "1", { `Break } } }
        string  s:
lua5.1: ERROR: assert fail at line ~598
stack traceback:
        [C]: in function 'error'
        test.lua:645: in main chunk
        [C]: ?
tst2005/lua-parser$

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.