crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Compile error in cross-referenced recursive function

Open HOMODELUNA opened this issue 1 year ago • 0 comments

Compile error in cross-referenced recursive function

Here is a toy parser. Its first and only parsing function is Grammar::recursive_descent, which used a auxillary function named rd_do_one_rule:

class Grammar
  #some other member function and variables......

  def recursive_descent(token_stream : Enumerable(Token),symbol = :S) : {AST?,Enumerable(Token)}
    @production[symbol].each do |rule|
      STDERR.puts "rule is ",rule.inspect
      ast,rest = rd_do_one_rule(token_stream,rule,symbol)
      if ast
        return {ast,rest}
      end
    end
    return {nil,token_stream}
  end
  private def rd_do_one_rule(token_stream : Enumerable(Token),rule : Rule , symbol = :S) : {AST?,Enumerable(Token)}
    pattern,callback= rule
    STDERR.puts "one rule:: rule is",pattern.inspect
    STDERR.puts "callback is",callback.inspect
    STDERR.puts "tokens is ",token_stream.inspect
    arr,rest_tokens = pattern.reduce({[]of Token| AST,token_stream}) do |arr_prev,entry|
      prev_arr,previous_stream = arr_prev
      STDERR.puts "stream is #{previous_stream}"
      case entry
      when ID
        if previous_stream.size >1 && entry === previous_stream.first
          {prev_arr.push(previous_stream.first),previous_stream.skip(1)}
        else
          return {nil,token_stream}
        end
      when Symbol
        ast,rest = recursive_descent(previous_stream,entry)
        if ast
          {prev_arr.push(ast),rest}
        else
          return {nil,token_stream}
        end
      else
        raise "what did you wirte in your syntax rule?"
      end
    end
    ast = callback(arr)
    return {ast,rest_tokens}
  end
end

the full repository is here, you can recall this error by crystal spec or crystal build .\spec\recursive_descent_spec.cr 2> err.txt

These two functions won't compile, and raises a stack-overflow error. I wonder if these function requires the conpiler to generate an infinite amount of specializations.

crystal : Stack overflow (e.g., infinite or very deep recursion)
location row:1 symbol: 1
+ crystal build .\spec\recursive_descent_spec.cr 2> err.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Stack overflow ...deep recursion):String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
$cr_compile> crystal --version
Crystal 1.5.0 [994c70b10] (2022-07-06)

LLVM: 13.0.0
Default target: x86_64-pc-windows-msvc

HOMODELUNA avatar Aug 14 '22 08:08 HOMODELUNA