in the anltr4 java grammar(https://github.com/antlr/grammars-v4/blob/master/java/Java.g4) I would like to know when I have the complete expression. In this example I am trying to make a transformation similar to the following:
from: String foo = bar + ", " + baz + "; are true";
to: String foo = String.format("{0}, {1}; are true", bar, baz);
The trouble begins in the declaration from the grammar:
expression ('+'|'-') expression"
which is a child of expression as well. Given the example above, the callbacks will look something like the following:
0: exp0:bar, exp1:","
1: exp0:bar ",", exp1:baz
2: exp0:bar "," baz, exp1:"; are true"
I am targeting the line using a #alias btw. So what I am awkwardly saying is - how do I use a listener to be able to grab the entire expression when a rule is expressed recursively in order to transform the entire expression? Or is there another way that I haven't seen yet?
Related
I want to make a macro that does this
mac1!("foo", x)
emits
foo(x)
is it even possible?
No, it's not possible. By the time the macro is expanded, the matching is done on the fact that "foo" is an expression (or a literal). The compiler does not distinguish between an expression like "foo" in your example and 123u8, 1 + 2, foo() or { let f = fs::read("foo.txt"); ... } as all of those are expressions. All the macro-by-example knows is that the first parameter is any kind of valid expression and it can't look deeper into it, because the compiler doesn't know what a "type" or a "value" is at this point.
You can use a procedural macro, which can use a parameter's value to generate new tokens, including identifiers.
Why do I see
proc simple(a, b: int) : int =
result = a + b
so often in nim code when it seems as if
proc simple(a, b: int) : int =
a + b
would suffice? Is there any semantic difference between those two that I'm missing?
The only reference to implicitly returning the last statement I found on nim-lang wasn't in the manual but in the tut where it states that
[...] a proc's body can consist of a single expression whose value is
then returned implicitly.
Which seems misleading: it seems as it works for every 'last expression' (unless result was already set, then the result of the statement has to be discarded)
In the coding conventions (https://nim-lang.org/docs/nep1.html#introduction-coding-conventions) they recommend to use return only if it's needed in the flow.
The book Nim in Action says 'it's not idiomatic to use the return keyword as the last statement of the proc', but it's not explicit about result = a + b vs a + b. From the snippets around the book, the convention seems to be:
Prefer a + b.
Use result = a + b only if you are modifying result, as in result.add(b).
Use return a only to do an early exit from the proc.
The book also list this gotcha that won't compile:
proc resultVar: string =
result = "The result"
"This cause an error"
The reason behind code like result = a + b or return a is that people can't get all the idiomatics, specially when they are beginners like me. I still see for i in range(len(variable)) in Python code, which is not only non-pythonic but ugly and underperformant.
One of the more exotic features is the implicit result variable: every procedure in Nim with a non-void return type has an implicit result variable that represents the value that will be returned [Wikipedia].
I'm messing around with Lua trying to create my own "scripting language".
It's actually just a string that is translated to Lua code, then executed through the use of loadstring. I'm having a problem with my string patterns. When you branch (for example, defining a variable inside of a variable declaration) it errors. For example, the following code would error:
local code = [[
define x as private: function()
define y as private: 5;
end;
]]
--defining y inside of another variable declaration, causes error
This is happening because the pattern to declare a variable first looks for the keyword 'define', and captures everything until a semicolon is found. Therefore, x would be defined as:
function()
define y as private: 5 --found a semicolon, set x to capture
I guess my question is, is it possible to ignore semicolons until the correct one is reached? Here is my code so far:
local lang = {
["define(.-)as(.-):(.-);"] = function(m1, m2, m3)
return (
m2 == "private" and " local " .. m1 .. " = " .. m3 .. " " or
m2 == "global" and " " .. m1 .. " = " .. m3 .. " " or
"ERROR IN DEFINING " .. m1
)
end,
}
function translate(code)
for pattern, replace in pairs(lang) do
code = code:gsub(pattern, replace)
end
return code
end
local code = [[
define y as private: function()
define x as private: 10;
end;
]]
loadstring(translate(code:gsub("%s*", "")))()
--remove the spaces from code, translate it to Lua code through the 'translate' function, then execute it with loadstring
The easiest solution is to to change your last capture group from
(.-) -- 0 or more lazy repetitions
to
(.*) -- 0 or more repetitions
i.e.
pattern = 'define(.-)as(.-):(.*);'
The - modifier according to PiL matches the shortest sequence.
However, as noted in my comment, I wouldn't advise writing a parser for your language using pattern matching. It will either require really complicated patterns (to prevent edge-cases) and probably be unclear to others.
I want to add non null items to a List. So I do this:
List<Foo> foos = []
Foo foo = makeFoo()
if (foo)
foos << foo
But is there a way to do it in a single operation (without using findAll after the creation of the list). Like:
foos.addNonNull(makeFoo())
Another alternative is to use a short circuit expression:
foo && foos << foo
The foo variable must evaluate to true for the second part to be evaluated. This is a common practice in some other languages but I'd hesitate to use it widely in groovy due to readability issues and conventions.
No, you'd need to use an if, or write your own addNonNull method (which just uses an if)
Also:
if( foo ) {
probably isn't enough, as this will skip empty strings, or 0 if it returns integers
You'd need
if( foo != null ) {
The answer is YES! we can get rid of assigning a variable
Foo foo = makeFoo()//we can ditch this
The answer is NO we can't get rid of the condition. BUT we can make it more compact.
Here's how
List<Foo> foos = []
foos += (makeFoo()?:[]);
The trick is groovy's "+" operator which works differently based on what is to the left and what is to the right of the "+". It just so happens that if what is on the left is a list and what is on the right is an empty list, nothing gets added to the list on the left.
Pros are it is quick to type and compact.
Cons are it is not instantly obvious what is happening to most people
AND we replaced the variable assignment with an extra operation. Groovy is
going to try to do something to List foos no matter what, it just so happens that in the second case the result of that operation gives us a desired result.
I've found a groovy code snippet similar to the next one:
def f1 = { print "Hello, ${it}" }
def f2 = { "world" }
(f2 >> f1)()
It looks like such construction works only between closures. This code also works with left shift operator ((f1 << f2)()).
I wonder how is this operator (or this technique) called?
It does closure composition.
See the rightShift and leftShift operator overloading API docs.
Overriding shift operators is a pretty common technique, like for adding items to a collection.
Here is a nice list of all operators with their names from the official documentation which displays the names of <<, >>, >>=, .., ..<, <<=, >>= and so on. Whenever I stumble upon something in Groovy I don't know the name of, this is the place to go (see also the paragraph on operator precedence on the same side).