JavaCC parser function calls - javacc

I am making a parser which handles multiple line input.
The input program define some functions and main line is for the result.
For example, define function A which has { x+3 } (x is parameter for function A).
If main line call function A such as MAIN { A(1+3) }, then how can I call the function A to calculate the expression in the MAIN line.

Normally your parser would translate the function to a representation that can be stored and interpreted later. See my answer to how do I implement loops (For) in javacc for more.

Related

Why is a Julia function name (without arguments) silently ignored?

I have a script that defines a function, and later intended to call the function but forgot to add the parentheses, like this:
function myfunc()
println("inside myfunc")
end
myfunc # This line is silently ignored. The function isn't invoked and there's no error message.
After a while I did figure out that I was missing the parentheses, but since Julia didn't give me an error, I'm wondering what that line is actually doing? I'm assuming that it must be doing something with the myfunc statement, but I don't know Julia well enough to understand what is happening.
I tried --depwarn=yes but don't see a julia command line switch to increase the warning level or verbosity. Please let me know if one exists.
For background context, the reason this came up is that I'm trying to translate a Bash script to Julia, and there are numerous locations where an argument-less function is defined and then invoked, and in Bash you don't need parentheses after the function name to invoke it.
The script is being run from command line (julia stub.jl) and I'm using Julia 1.0.3 on macOS.
It doesn't silently ignore the function. Calling myfunc in an interactive session will show you what happens: the call returns the function object to the console, and thus call's the show method for Function, showing how many methods are currently defined for that function in your workspace.
julia> function myfunc()
println("inside myfunc")
end
myfunc (generic function with 1 method)
julia> myfunc
myfunc (generic function with 1 method)
Since you're calling this in a script, show is never called, and thus you don't see any result. But it doesn't error, because the syntax is valid.
Thanks to DNF for the helpful comment on it being in a script.
It does nothing.
As in c, an expression has a value: in c the expression _ a=1+1; _ has the value _ 2 _ In c, this just fell out of the parser: they wanted to be able to evaluate expressions like _ a==b _
In Julia, it's the result of designing a language where the code you write is handled as a data object of the language. In Julia, the expression "a=1+1" has the value "a=1+1".
In c, the fact that
a=1+1;
is an acceptable line of code means that, accidentally,
a;
is also an acceptable line of code. The same is true in Julia: the compiler expects to see a data value there: any data value you put may be acceptable: even for example the data value that represents the calculated value returned by a function:
myfunc()
or the value that represents the function object itself:
myfunc
As in c, the fact that data values are everywhere in your code just indicates that the syntax allows data values everywhere in your code and that the compiler does nothing with data values that are everywhere in your code.

Can I add a method to a function to receive as an argument another particular function?

I've created my immutable Tensor_field and a function nabla that acts on the tensor (that is nabla(a::Tensor_field) = do something.
I've added a method to function dot for the tensor: Base.dot(a::Tensor_field, b::Tensor_field) = do something....
Now I want to define a new behavior to function dot with nabla as an argument.
Something like Base.dot(nabla::function, a::Tensor_field) = do something different.
I know in Julia we are able to pass functions as arguments to other functions, but I couldn't find in the docs how to define a method for a "functional" argument.
If I type typeof(nabla) the output is My_Module_Name.#nabla, not a real DataType...
If you want it to work for any function, you can do
Base.dot(f::Function, a::Tensor_field) = do something different
If you only want it to work for the nabla function already defined, you can take advantage of what you have discovered, namely that each function has a unique type:
Base.dot(f::typeof(nabla), a::Tensor_field) = do something different
This will match only the function called nabla, which will now be called f inside the function dot.
Note that you can write ∇ as \nabla<TAB> and use it in your code instead of the word nabla. If your tensor field is called e.g. 𝐯 (written as \mbfv<TAB>), you can then write ∇⋅𝐯 in your Julia code! (The centered dot is written as \cdot<TAB>, and is an alias for the dot function.)

Using flow to annotate a function that accepts another function

I understand the basic rules for annotating a function definition, e.g. if you want to assert that the first argument should always be a string, etc.
But what if you want to assert that the first argument should be another function? (Also, is it possible to specify what signature the passed function should have?)
I have attempted to work this out from the flow docs on functions but I am very confused, and some examples would be really helpful.
It looks something like this:
function myFunction(fn: (foo: string, bar: number) => Array<string>) {
}

Confusion with ' operator and bracketing where (v')*v becomes Ac_mul_B despite overloading

I am playing around with the idea of CoVectors in Julia and am getting some behaviour I didn't expect from the parser/compiler. I have defined a new CoVector type that is the ctranspose of any vector, and is just a simple decoration:
type CoVector{T<:AbstractVector}
v::T
end
They can be created (and uncreated) with ' using ctranspose:
import Base.ctranspose
function CoVector(T::DataType,d::Integer=0)
return CoVector(Array(T,d))
end
function Base.ctranspose(cv::CoVector)
return cv.v
end
function Base.ctranspose(v::AbstractVector)
return CoVector(v)
end
function Base.ctranspose(v::Vector) # this is already specialized in Base
return CoVector(v)
end
Next I want to define a simple dot product
function *(x::CoVector,y::AbstractVector)
return dot(x.v,y)
end
Which can work fine for:
v = [1,2,3]
cv = v'
cv*v
returns 14, and cv is a CoVector. But if I do
(v') * v
I get something different! In this case it is a single element array containing 14. How come parenthesis doesn't work how I expect?
In the end we see the expression gets expanded to Ac_mul_B which defaults to [dot(A,B)] and it seems that this interpretation is defined at the "operator" level.
Is this expected behaviour? Can Julia completely ignore my bracketing and change the expression as it wants? In Julia I like that I can override things in Base but is it also possible to make self-consistent changes to how operators are applied? I see the expression doesn't have head call but Symbol call... does this change in Julia 0.4? (I read somewhere that call is becoming more universal).
I guess I can fix the problem by redefining Ac_mul_B but I was very surprised that it was called at all, given my above definitions.

Vector{AbstractString} function parameter won't accept Vector{String} input in julia

The following code in Julia:
function foo(a::Vector{AbstractString})
end
foo(["a"])
gives the following error:
ERROR: MethodError: no method matching foo(::Array{String,1})
Closest candidates are:
foo(::Array{AbstractString,1}) at REPL[77]:2
Even though the following code runs, as expected:
function foo(a::Vector{String})
end
foo(["a"])
And further, AbstractString generally matches String as in:
function foo(::AbstractString)
end
foo("a")
How can I call a function with a Vector{AbstractString} parameter if I have String elements?
You need to write the function signature like this:
function foo{S<:AbstractString}(a::Vector{S})
# do stuff
end
On Julia 0.6 and newer, it's also possible to write instead
function foo(a::Vector{<:AbstractString})
# do stuff
end
This is a consequence of parametric type invariance in Julia. See the chapter on types in the manual for more details.

Resources