lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 08/25/2017 09:22 AM, Peter Melnichenko wrote:
> On Fri, Aug 25, 2017 at 10:24 AM, Michael Rosenberg <rosenbmi@umich.edu> wrote:
>> Sorry to revive an old thread. Here's an ambiguity you would introduce into the grammar if you implemented the rule
>> var ::=  Name | tableconstructor ‘[’ exp ‘]’ | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
>> Consider the following
>>
>> function foo(_)
>>   return {"x", "y", "z"}
>> end
>> v = foo {"a", "b", "c"} [2]
>> print(type(v))
>>
>> What is printed? If {"a", "b", "c"}[2] is evaluated first, then foo("b") is a table. If foo {"a", "b", "c"} is evaluated first, then {"x", "y", "z"}[2] is a string. The same ambiguous situation happens with the use of the dot operator and the colon operator.
> 
> This is not ambiguous. `functioncall` requires `args` at the end, and
> `args` can only match `{"a", "b", "c"}` here, not `{"a", "b",
> "c"}[2]`. So the indexing can't be an argument, and it can't be a
> standalone statement either.
> 
> If you add another call at the end, that makes it ambiguous: `v = f
> {g} [1] ()` could be a single statement or two, equivalent to `v = f;
> {g} [1] ()`. This is similar to how `v = f (g) (h)` is ambiguous in
> original Lua grammar.
> 
> Ref:
> 
>     functioncall ::=  prefixexp args | prefixexp ‘:’ Name args
>     args ::=  ‘(’ [explist] ‘)’ | tableconstructor | LiteralString
> 
> -- Peter

Yes, it is not ambiguous for greedy Lua parser, which eats longest
sequence it can.


By the way, if we change <var> rule

  var ::=  Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name

not to

  var ::=  Name | tableconstructor ‘[’ exp ‘]’ | prefixexp ‘[’ exp ‘]’ |
prefixexp ‘.’ Name

but to

  var ::=  Name | tableconstructor | prefixexp ‘[’ exp ‘]’ | prefixexp
‘.’ Name

we can have "." indexing too:

  a = {x = 1, y = {re = 2, im = 3}}.y.re


Similar manner we may get rid of () around string literals:

  var ::=  Name | LiteralString | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name

=>

  msg = 'value: %s':format(v)


Regarding grammar, I doubt in usefulness of rule

  args ::=  ‘(’ [explist] ‘)’ | tableconstructor | LiteralString

Yes, with it we may do Python-like

  require 'penlight'

but also create puzzles like

  f{a, b, c}[2]{x}

  -- f = function(...) return ... end; b = function(t) return t[1] end;
x = 'X'


(The full Lua grammar is available at
https://www.lua.org/manual/5.3/manual.html#9 )

-- Martin