JustAnswer のしくみ:
  • 専門家に質問
    知識豊富な専門家があらゆる質問にお答えするために常に待機しています。
  • 専門家が丁寧に対応
    E メールやサイト内オンラインメッセージなど、さまざまな手段で回答を通知。必要に応じてフォローアップの質問をすることもできます。
  • 満足度 100% 保証
    専門家からの回答を確認し評価をすることで、支払うかどうかを決めます。
rushqkに今すぐ質問する
rushqk
rushqk, プログラマー
カテゴリ: プログラミング
満足したユーザー: 766
経験:  AV機器開発、ソフトウェア設計
60440014
ここに プログラミング に関する質問を入力してください。
rushqkがオンラインで質問受付中

JAVA C if,for,while,do if_statement

質問者の質問

コンパイラコードを作成しています。JAVAで記載されたCプログラムフォーマッターに、if,for,while,do文の記述を追加したいのですが、
if_statement ::=
if (expression)
statement
[else
statement]
for_statement ::=
for ([expression]; [expression]; [expression])
statement
while_statement ::=
while (expression)
statement
do_statement ::=
do
statement
while (expression);

Formatクラスの中のどこにどのように記載すればよいのかわかりません。
もしおわかりになればだいたいで結構ですのでご教授ください。
Formatクラスは、以下の通りです。
// The Format class contains the methods necessary for formatting a
// C program. Only the file method is public. Recursive descent
// parsing is used to parse the program and perform the formatting.

class Format
{
private Lexer lexer;
private Output output;
private Token token;

// The constructor establishes the input lexer and the output
// private data members.

public Format(Lexer lexer, Output output)
{
this.lexer = lexer;
this.output = output;
}

// file is the only public method. External
// declarations are formatted until a function is found, at
// which time functionBody is called to format it.

public void file()
{
token = lexer.getNextToken();
while (token != Token.END_OF_FILE)
if (externalDeclaration())
functionBody();
}

// functionBody formats the declarations and statements in a
// function body.

private void functionBody()
{
output.endLine(true);
while (token == Token.TYPE_SPECIFIER ||
token == Token.SC_SPECIFIER ||
token == Token.STRUCT || token == Token.UNION ||
token == Token.UPPER_CASE_IDENTIFIER)
parameterDeclaration();
output.indent();
output.endLine(false);
output.skipLine();
compoundStatement();
output.unindent();
output.endLine(false);
output.endPage();
}

// compoundStatement formats a multiple statement block

private void compoundStatement()
{
int noOfDeclarations= 0;
token = lexer.getNextToken();
output.endLine(false);
while (token == Token.TYPE_SPECIFIER ||
token == Token.SC_SPECIFIER ||
token == Token.STRUCT || token == Token.UNION ||
token == Token.UPPER_CASE_IDENTIFIER)
{
declaration();
noOfDeclarations++;
}
if (noOfDeclarations > 0)
output.skipLine();
while (token != Token.RIGHT_BRACE)
statement();
token = lexer.getNextToken();
output.endLine(false);
}

// statement determines the type of statement and calls the
// appropriate function to format it.

private void statement()
{
if (token == Token.IDENTIFIER)
if ((token = lexer.getNextToken()) == Token.COLON)
token = lexer.getNextToken();
else
{
token = Token.IDENTIFIER;
lexer.putLastToken();
}
switch (token)
{
case LEFT_BRACE:
compoundStatement();
break;
case SWITCH:
switchStatement();
break;
case BREAK:
case CONTINUE:
verifyNextToken(Token.SEMICOLON);
output.endLine(false);
break;
case RETURN:
if ((token = lexer.getNextToken()) != Token.SEMICOLON)
{
expression(Token.SEMICOLON);
token = lexer.getNextToken();
}
else
token = lexer.getNextToken();
output.endLine(false);
break;
case GOTO:
verifyNextToken(Token.IDENTIFIER);
verifyNextToken(Token.SEMICOLON);
output.endLine(false);
break;
default:
expression(Token.SEMICOLON);
token = lexer.getNextToken();
output.endLine(false);
}
}

// switchStatement formats a switch statement.

private void switchStatement()
{
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
verifyCurrentToken(Token.LEFT_BRACE);
output.endLine(false);
while (token == Token.CASE || token == Token.DEFAULT)
{
expression(Token.COLON);
lexer.adjustSpacing(Lexer.SUPPRESS_LEADING_SPACE);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
while (token != Token.CASE && token != Token.DEFAULT &&
token != Token.RIGHT_BRACE)
statement();
output.unindent();
}
verifyCurrentToken(Token.RIGHT_BR
投稿: 6 年 前.
カテゴリ: プログラミング
専門家:  rushqk 返答済み 6 年 前.

質問ありがとうございます。

 

statement()に追加すればよいのではないでしょうか。

例えばforの場合は

case FOR:
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.SEMICOLON);
expression(Token.SEMICOLON);
expression(Token.RIGHT_PARENTHESIS);
statement();
break;

 

いかがでしょう。

rushqkをはじめその他名のプログラミングカテゴリの専門家が質問受付中
質問者: 返答済み 6 年 前.

ご回答ありがとうございます。

試しにご教授の通りプログラムを記載してみます。その後質問が出るかもしれませんので、少々お待ちいただけますか。

よろしくお願いします。

専門家:  rushqk 返答済み 6 年 前.

了解いたしました。

質問者: 返答済み 6 年 前.

ご教授のように、フォーマットクラスstatement()内のcase文の追加記載と、更にメソッドを追加しましたが、if文の記述(特にELSE文)がよくわからないので、どう記述したらよいかご教授願えますか。変更するのはFormatクラスのみで構いません。又他の追加記載箇所に間違いがあればご指摘ください。

 

 

Format.java

http://firestorage.jp/download/5f961eb6c95007649f2e09593730e90511f1c90b

 

使用したクラスは以下4つを含めた5つです。

 

Lexer.java

http://firestorage.jp/download/c2d49c6c6ca09002f9d5e0ab3e4f114df6ef926c

 

Main.java

http://firestorage.jp/download/25c5c667291c6b6a8b7f7b571114c7b2759d8b2b

 

Output.java

http://firestorage.jp/download/af6c274d7f36f6935f50ed9fb0350e681db77c29

 

Token.java

http://firestorage.jp/download/d1e8eabe3062a8a46b33bf38d9224a9640c862aa

 

 

テストケースも添付しておきます。

 

test0.c

http://firestorage.jp/download/116500f8e09d48e40056c13ba29a661aee33e13a

 

test1.c

http://firestorage.jp/download/1afbbc8a8521d45e18f46699edc163b473ff6b64

 

test2.c

http://firestorage.jp/download/0b7c4c0d2fe5ff413d86c2d3f8f920165d87218f

 

 

専門家:  rushqk 返答済み 6 年 前.

拝見させていただきました。

ELSEには特に条件が無いので

{

statement();
output.endLine(false);

}

のみでよいと思います。

 

質問者: 返答済み 6 年 前.

私の言葉が足りなかったようです。
質問したかったのはif_statement()の中にELSE文も含めて記載するにはどのように記載したらよいか、ということでした。

0 if_statement ::=
1 if (expression)
2 statement
3 [else statement]

のうちの0-2行については

private void if_statement(){
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
statement();
output.endLine(false);
になるかと思われますが、3行目[else statement]をこの後に追加記載するにはどのように記載したらよいでしょうか。if_statement()のなかにELSE文についてもまとめて記載したいのです。
この場合Format classのstatement()内の
case IF:
if_statement();
break;

case ELSE:
statement();
output.endLine(false);
// break; ここは削除すべきとのことで宜しいでしょうか。
の記載には変化はありますでしょうか。変えるべきであればどのように変えるべきか教えていただけますか。

それでは宜しくお願いします。

専門家:  rushqk 返答済み 6 年 前.

ELSEの後のBreakは消さないでください。

とりあえず、こんな感じでしょうか。

private void if_statement(){

verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
statement();
token = lexer.getNextToken();
if { token == ELSE ){
   token = lexer.getNextToken();

statement();
}
output.endLine(false);
}