1

加算と減算を解析するための単純な JavaCC 文法があると仮定しましょう。


....
void CompilationUnit() :
{}
{
  (Expression())+
  EOF
}
void Expression() :
{}
{
  Number()
  (
    Addition()
  | Subtraction()
  )*
}
void Number() :
{}
{
  
}
void Addition() :
{}
{
   Number()
}
void Subtraction() :
{}
{
   Number()
}

この文法によって生成された AST を使用して結果を計算するクラスがあります。


public class Calculator extends DepthFirstVisitor {
  int result = -1;
  public void visit(Expression n) {
    if (result >= 0) System.out.println(toText(n) + " = " + result);
    result = 0;
    super.visit(n);
  }
  public void visit(Number n) {
    ...
  }
  public void visit(Addition n) {
    ...
  }
  ....
}

式の値を計算することはできますが、元の式も必要です (表示どおり)。したがって、次の入力の場合:

  5 + 2 - 1
  2 + 1

次の出力が必要です。

5 + 2 - 1 = 6
2 + 1 = 3

残念ながら、スペースや改行などの文字をスキップしているため、次のようになります。

5+2-1 = 6
2+1 = 3

元のテキスト (スキップされた文字を含む) を出力する方法はありますか?

実際の問題はもっと大きく、文法はもっと複雑であることに注意してください。したがって、上記の問題に固有の解決策(たとえば、行を前処理して改行文字で分割するか、メソッドを変更して各トークンの後にスペースを「手動で」追加するなど)を実際に探しているわけではありませんが、JavaCC機能を使用している解決策に似ています.

4

2 に答える 2

2

ANTLr と Xtext はどちらも、空白とコメントの「隠しトークン」をサポートしています。ヒントについてはこちらを参照するか、その用語で Google を使用してください。おそらく、JavaCC にも同様の概念があります。

EDIT:JavaCCは「特別なトークン」という用語を使用しているようです。詳細については、こちらを参照してください

于 2013-05-01T11:20:13.403 に答える
0

基本的に、コンパイラでこれを行うことはできません。文法内のトークンとして空白をキャプチャし、許可されているすべての場所でそれを許可する必要があります。これはどこでも可能であり、結果の文法は非常に複雑になり、実装または生成することさえできなくなります。エンティティの元となったソース コード (行と列) の座標への参照を取得する必要があります。たとえば、現在の行と列番号のテキストなどです。

コンパイラがそのように動作するのには理由があります。

于 2013-05-01T10:27:34.930 に答える