据报道,简单表达式在解析器组合器中是递归的

时间:2015-12-26 13:27:56

标签: scala recursion overloading override parser-combinators

猜猜这个编译的结果是什么?

import scala.util.parsing.combinator._

object ExprParser extends JavaTokenParsers {
    lazy val literal = int  
    lazy val int = rep("0")
}

编译器说int is recursive and asks for the type of it。我的实验说,递归的核心隐藏在文字的声明中!删除它,你会看到递归消失了!

1 个答案:

答案 0 :(得分:5)

此处JavaTokenParsers定义了名为literal的内容。

rep("0")实际上是rep(literal("0"))literal是从StringParser[String]的隐式转换。

但是literal中的JavaTokenParsers需要参数,而你的int没有。所以你可能会期望你的只是重载,而不是覆盖,并且不存在冲突 - literalobject ExprParser extends JavaTokenParsers { lazy val literal: Parser[List[String]] = int lazy val int: Parser[List[String]] = rep("0") } 之间没有相互递归。

事实上,如果你提供显式类型:

literal

这对编译器来说很好。

那么为什么在省略返回类型时会触发递归的显式返回类型规则?

我认为这是一个相当微妙的问题。我不确定我确切知道这里发生了什么。我在Scala语言规范中找不到涵盖它的特定语言。

我最好的猜测是,在触发显式返回类型规则时,编译器仍然处于相对较早的阶段,它尚未准确地解决了什么或不是重载或覆盖。还没有返回类型,它必须基于有关类型的部分信息继续进行。

但它确实知道您对int的定义涉及名称int,而您对literal的定义涉及名称static class BluetoothInHandler extends Handler { private final WeakReference<Bluetooth_dataDisplay> mActivity; BluetoothInHandler(Bluetooth_dataDisplay activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { //change 3 Log.e("test","handleMessage"); final Bluetooth_dataDisplay thizz = mActivity.get(); if (thizz == null) return; if (msg.what == thizz.handlerState) { String readMessage = (String) msg.obj; thizz.myLabel.setText(readMessage); } }//end of handle message }//end of Bluetoothin handler @Override public void onResume() { super.onResume(); String MAC = getIntent().getStringExtra("MAC"); mAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC); ConnectingThread t = new ConnectingThread(bluetoothDevice,mMyHandler ); t.start(); } //Setting Up a Connecting Client private class ConnectingThread extends Thread { OutputStream mmOutputStream; InputStream mmInputStream; StringBuilder recDataString = new StringBuilder(); // private final BluetoothSocket bluetoothSocket; private final BluetoothDevice bluetoothDevice; Handler handler; public ConnectingThread(BluetoothDevice device,Handler mHandler) { handler = mHandler BluetoothSocket temp = null; bluetoothDevice = device; // Get a BluetoothSocket to connect with the given BluetoothDevice try { temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid); } catch (IOException e) { e.printStackTrace(); } bluetoothSocket = temp; } public void run() { // Cancel any discovery as it will slow down the connection mAdapter.cancelDiscovery(); try { // This will block until it succeeds in connecting to the device // through the bluetoothSocket or throws an exception bluetoothSocket.connect(); Log.e("bluetooth socket",".connect"); mmOutputStream = bluetoothSocket.getOutputStream(); mmInputStream = bluetoothSocket.getInputStream(); //beginListenForData(); Bluetooth_dataDisplay.this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(Bluetooth_dataDisplay.this, "Connected with Device!", Toast.LENGTH_SHORT).show(); } }); //change 7 //handler.post( new Runnable() { public void run() { byte[] buffer = new byte[1024]; int bytes; // Keep looping to listen for received messages while (true) { //change 1 try{ Thread.sleep(1000); }catch(Throwable e){ e.printStackTrace(); } try { bytes = mmInputStream.read(buffer); String readMessage = new String(buffer, 0, bytes); // Send the obtained bytes to the UI Activity via handler //change 4; handler.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget(); } catch (IOException e) { //change 6 Log.e("test","6") //change 2 e.printStackTrace(); break; }catch(Throwable e1){ //change 5; Log.e("test","5") } } }.run(); //}); //beginListenForData(); //Log.e("begin", "begindata"); } catch (IOException connectException) { connectException.printStackTrace(); try { bluetoothSocket.close(); Log.e("click6", "blueclose"); } catch (IOException closeException) { closeException.printStackTrace(); } } } ,因此它认为递归和放弃了。