Using a single quote (') character as a suffix operator in MetaLua

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Using a single quote (') character as a suffix operator in MetaLua

Jaco van der Merwe
I am using MetaLua to extend the syntax of Lua to provide Matlab-like operators on matrix objects. So far I've sucessfully implemented most of the unary and binary operators of Matlab that aren't provided in standard Lua. The one that is giving problems is the matrix transpose operator. In Matlab, the transpose of a matrix M is denoted by M'. The MetaLua code should replace this with a method call to the transpose() function. Here is the MetaLua code:


-{
    mlp.lexer:add "'"
    mlp.expr.suffix:add {"'", prec = 100, builder = |a, _| `Invoke{a, `String "transpose"}}
 }

M = {}
function M:transpose()
    return "M transposed"
end

print( M' )


The MetaLua parser fails parsing the line containing "M'" with an "Unterminated string" error. When I change the transpose operator to another character like "!", or "@" it works perfectly. However, the unconjugated transpose operator (.') works despite the fact that it contains a single quote as shown below:


-{
    mlp.lexer:add ".'"
    mlp.expr.suffix:add {".'", prec = 100, builder = |a, _| `Invoke{a, `String "unconj_transpose"}}
 }

M = {}
function M:unconj_transpose()
    return "M transposed unconjugated"
end

print( M.' )


I would really like to be able to use the single quote character as the transpose operator. I can understand that the lexer doesn't like an unterminated string, but in this case it should fall back and check if the terminator isn't used as unary operator. I also do not understand why ".'" works, but "'" doesn't.



Reply | Threaded
Open this post in threaded view
|

Re: Using a single quote (') character as a suffix operator in MetaLua

Fabien-3


On Tue, Oct 18, 2011 at 12:31 PM, Jaco van der Merwe <[hidden email]> wrote:
In Matlab, the transpose of a matrix M is denoted by M'. The MetaLua code should replace this with a method call to the transpose() function.

Your problem is that in the lexer, string lexing has a higher priority than keyword lexing, so the single quote is parsed as a string, and never considered by the symbol-keyword extractor. Moreover, the symbol extractor has to keep the lowest priority, because it always succeeds at finding a symbol (this could be changed, but it never occurred to me that it made sense).

So what you need to do is add an extractor in the lexer, which recognizes the quote, and has higher priority than the short_string_extractor:

$ cat > prime.mlua
-{ block:

   mlp.expr.suffix:add{ "'", prec=100, builder=|a| +{-{a}:transpose()} }

   function lexer.lexer:extract_prime()
       local k = self.src :sub(self.i, self.i)
       if k=="'" then self.i=self.i+1; return "Keyword", "'"
       else return end
   end

   table.insert(lexer.lexer.extractors, 2, "extract_prime")
}

table.print(+{ f'})
^D
$ metalua prime.mlua
`Invoke{ `Id "f", `String "transpose" }
$ _

Beware that with this modification, Metalua won't recognize single-quote strings anymore. This is unavoidable, has sources such as " f' * g' " would become ambiguous, between " f(" * g") " and " f:transpose() * g:transpose() ". There must be clever ways to analyze single quotes in a context-aware way, but I wouldn't recommend that, it would introduce needless headaches and corner-cases for end-users.

For further Metalua enquiries, you can also ask the dedicated mailing list, which recently moved to google groups: http://groups.google.com/group/metalua

-- Fabien.
Reply | Threaded
Open this post in threaded view
|

RE: Using a single quote (') character as a suffix operator in MetaLua

Jaco van der Merwe
Thank you Fabien, that solves my problem.

Just for my own understanding, why did the ".'" operator work? Wouldn't it also be seen as a string terminator?



Reply | Threaded
Open this post in threaded view
|

Re: Using a single quote (') character as a suffix operator in MetaLua

Fabien-3


On Tue, Oct 18, 2011 at 2:19 PM, Jaco van der Merwe <[hidden email]> wrote:
Thank you Fabien, that solves my problem.

Just for my own understanding, why did the ".'" operator work? Wouldn't it also be seen as a string terminator?

Because it starts with a dot, so the string lexer realizes it's not a string and skips it. Once it has a chance to be seen by the keyword lexer, it will be lexed completely and correctly.
 
Your problem with the quote "'" was that the string lexer recognized it, so it never had a chance to be seen by lower priority lexers, including the symbol keywords parser.
Reply | Threaded
Open this post in threaded view
|

Re: Using a single quote (') character as a suffix operator in MetaLua

Rena
On Tue, Oct 18, 2011 at 06:32, Fabien <[hidden email]> wrote:

>
>
> On Tue, Oct 18, 2011 at 2:19 PM, Jaco van der Merwe <[hidden email]>
> wrote:
>>
>> Thank you Fabien, that solves my problem.
>>
>> Just for my own understanding, why did the ".'" operator work? Wouldn't it
>> also be seen as a string terminator?
>
> Because it starts with a dot, so the string lexer realizes it's not a string
> and skips it. Once it has a chance to be seen by the keyword lexer, it will
> be lexed completely and correctly.
>
> Your problem with the quote "'" was that the string lexer recognized it, so
> it never had a chance to be seen by lower priority lexers, including the
> symbol keywords parser.

Could you use M` instead?

--
Sent from my toaster.