diff --git a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java index 4bf124a..b42a607 100644 --- a/AlgebraicDataflowArchitectureModel/src/parser/Parser.java +++ b/AlgebraicDataflowArchitectureModel/src/parser/Parser.java @@ -61,6 +61,9 @@ public static final String DOT_REGX = "\\."; public static final String DOUBLE_QUOT = "\""; + public static final String SINGLE_LINE_COMMENT = "//"; + public static final String SINGLE_LINE_COMMENT_REGX = "\\/\\/"; + public Parser(final TokenStream stream) { this.stream = stream; } @@ -730,7 +733,10 @@ public void addLine(String line) { lines.add(line); - line = line.trim(); + line = removeComments(line.trim()); + if (line.isBlank()) { + return; + } ArrayList tokenList = splitByDoubleQuotation(line); tokenList = splitBy(tokenList, ADD, ADD_REGX); tokenList = splitBy(tokenList, MUL, MUL_REGX); @@ -785,6 +791,25 @@ return newTokens; } + /** + * Removes single-line comment from given line. + * + * @param line The line of text to be processed + * @return The line of text without single-line comment. + * @author Shohei Yamagiwa + */ + private String removeComments(String line) { + StringBuilder result = new StringBuilder(); + String[] tokens = line.split(" "); + for (String token : tokens) { + if (token.equals(SINGLE_LINE_COMMENT)) { + break; + } + result.append(token).append(" "); + } + return result.toString(); + } + private ArrayList splitByDoubleQuotation(String line) { ArrayList newTokens = new ArrayList<>(); String[] tokens = line.split(DOUBLE_QUOT); diff --git a/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/CommentTest.java b/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/CommentTest.java deleted file mode 100644 index 96fdda6..0000000 --- a/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/CommentTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package tests.parser.comment; - -import models.algebra.Symbol; -import models.algebra.Term; -import models.algebra.Variable; -import models.dataConstraintModel.ChannelMember; -import models.dataConstraintModel.JsonTerm; -import models.dataConstraintModel.ResourcePath; -import models.dataConstraintModel.StateTransition; -import models.dataFlowModel.DataTransferChannel; -import models.dataFlowModel.DataTransferModel; -import org.junit.Test; -import parser.Parser; -import parser.exceptions.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import static org.junit.Assert.assertEquals; - -public class CommentTest { - @Test - public void test() { - try (InputStream in = getClass().getResourceAsStream("SingleLineComment.model")) { - assert in != null; - Parser parser = new Parser(new BufferedReader(new InputStreamReader(in))); - try { - DataTransferModel actual = parser.doParse(); - DataTransferModel expected = getExpectedModel(); - // FIXME: Should assert by comparison of object members, not string equality - assertEquals(expected.toString(), actual.toString()); - } catch (ExpectedAssignment | WrongLHSExpression | ExpectedInOrOutOrRefOrSubKeyword | WrongJsonExpression | - WrongPathExpression | ExpectedRightCurlyBracket | ExpectedChannelName | ExpectedStateTransition | - ExpectedRightBracket | ExpectedRHSExpression | WrongRHSExpression | ExpectedEquals | - ExpectedLeftCurlyBracket | ExpectedColon | ExpectedDoubleQuotation | ExpectedChannel e) { - throw new RuntimeException(e); - } - } catch (RuntimeException | IOException e) { - throw new RuntimeException(e); - } - } - - private DataTransferModel getExpectedModel() { - ResourcePath accountsPath = new ResourcePath("accounts"); - ResourcePath accountPath = new ResourcePath(accountsPath, new Variable("accountId")); - ResourcePath usernamePath = new ResourcePath(accountPath, "username"); - ResourcePath emailPath = new ResourcePath(accountPath, "email"); - ResourcePath passwordPath = new ResourcePath(accountPath, "password"); - - DataTransferChannel createAccountChannel = new DataTransferChannel("CreateAccount"); - ChannelMember accountsChannelMember = new ChannelMember(accountsPath); - createAccountChannel.addChannelMemberAsOutput(accountsChannelMember); - - StateTransition transition = new StateTransition(); - transition.setCurStateExpression(getAccountsVariable()); - transition.setMessageExpression(getCreateAccountTerm()); - transition.setNextStateExpression(getInsertTerm()); - accountsChannelMember.setStateTransition(transition); - - DataTransferModel model = new DataTransferModel(); - model.addResourcePath(usernamePath); - model.addResourcePath(emailPath); - model.addResourcePath(passwordPath); - model.addInputChannel(createAccountChannel); - return model; - } - - private Variable getAccountsVariable() { - return new Variable("accounts", DataTransferModel.typeMap); - } - - private Term getCreateAccountTerm() { - Symbol createAccount = new Symbol("createAccount", 4); - Variable accountId = new Variable("accountId", DataTransferModel.typeInt); - Variable username = new Variable("username", DataTransferModel.typeString); - Variable email = new Variable("email", DataTransferModel.typeString); - Variable password = new Variable("password", DataTransferModel.typeString); - Term term = new Term(createAccount); - term.addChild(accountId); - term.addChild(username); - term.addChild(email); - term.addChild(password); - return term; - } - - private Term getInsertTerm() { - Variable accounts = new Variable("accounts"); - Variable accountId = new Variable("accountId"); - JsonTerm jsonBody = new JsonTerm(); - Variable username = new Variable("username"); - Variable email = new Variable("email"); - Variable password = new Variable("password"); - jsonBody.addMember("username", username); - jsonBody.addMember("email", email); - jsonBody.addMember("password", password); - Symbol insert = new Symbol("insert", 3); - Term term = new Term(insert); - term.addChild(accounts); - term.addChild(accountId); - term.addChild(jsonBody); - return term; - } -} diff --git a/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineComment.model b/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineComment.model index d3554d6..b6c42f6 100644 --- a/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineComment.model +++ b/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineComment.model @@ -1,8 +1,6 @@ -// A channel for create account! -channel CreateAccount { - // A comment inside the channel! - out accounts(accounts: Map, createAccount(accountId: Int, username: Str, email: Str, password: Str)) = insert(accounts, accountId, {"username": username, "email": email, "password": password}); // A comment to describe this line - // - // Comment above is an empty comment -} -// 日本語で書かれたコメントです。これが最後の行です。 \ No newline at end of file +// A single line comment here +channel CreateAccount { // A channel for account creation + // A comment inside channels + out accounts(accounts: Map, createAccount(accountId: Int, username: Str, email: Str, password: Str)) = insert(accounts, accountId, {"username": username, "email": email, "password": password}) // The comment to describe this line. +} // Unexpected comment here! +// Final line comment here \ No newline at end of file diff --git a/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineCommentTest.java b/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineCommentTest.java new file mode 100644 index 0000000..a7d394b --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/tests/parser/comment/SingleLineCommentTest.java @@ -0,0 +1,105 @@ +package tests.parser.comment; + +import models.algebra.Symbol; +import models.algebra.Term; +import models.algebra.Variable; +import models.dataConstraintModel.ChannelMember; +import models.dataConstraintModel.JsonTerm; +import models.dataConstraintModel.ResourcePath; +import models.dataConstraintModel.StateTransition; +import models.dataFlowModel.DataTransferChannel; +import models.dataFlowModel.DataTransferModel; +import org.junit.Test; +import parser.Parser; +import parser.exceptions.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static org.junit.Assert.assertEquals; + +public class SingleLineCommentTest { + @Test + public void test() { + try (InputStream in = getClass().getResourceAsStream("SingleLineComment.model")) { + assert in != null; + Parser parser = new Parser(new BufferedReader(new InputStreamReader(in))); + try { + DataTransferModel actual = parser.doParse(); + DataTransferModel expected = getExpectedModel(); + // FIXME: Should assert by comparison of object members, not string equality + assertEquals(expected.toString(), actual.toString()); + } catch (ExpectedAssignment | WrongLHSExpression | ExpectedInOrOutOrRefOrSubKeyword | WrongJsonExpression | + WrongPathExpression | ExpectedRightCurlyBracket | ExpectedChannelName | ExpectedStateTransition | + ExpectedRightBracket | ExpectedRHSExpression | WrongRHSExpression | ExpectedEquals | + ExpectedLeftCurlyBracket | ExpectedColon | ExpectedDoubleQuotation | ExpectedChannel e) { + throw new RuntimeException(e); + } + } catch (RuntimeException | IOException e) { + throw new RuntimeException(e); + } + } + + private DataTransferModel getExpectedModel() { + ResourcePath accountsPath = new ResourcePath("accounts"); + ResourcePath accountPath = new ResourcePath(accountsPath, new Variable("accountId")); + ResourcePath usernamePath = new ResourcePath(accountPath, "username"); + ResourcePath emailPath = new ResourcePath(accountPath, "email"); + ResourcePath passwordPath = new ResourcePath(accountPath, "password"); + + DataTransferChannel createAccountChannel = new DataTransferChannel("CreateAccount"); + ChannelMember accountsChannelMember = new ChannelMember(accountsPath); + createAccountChannel.addChannelMemberAsOutput(accountsChannelMember); + + StateTransition transition = new StateTransition(); + transition.setCurStateExpression(getAccountsVariable()); + transition.setMessageExpression(getCreateAccountTerm()); + transition.setNextStateExpression(getInsertTerm()); + accountsChannelMember.setStateTransition(transition); + + DataTransferModel model = new DataTransferModel(); + model.addResourcePath(usernamePath); + model.addResourcePath(emailPath); + model.addResourcePath(passwordPath); + model.addInputChannel(createAccountChannel); + return model; + } + + private Variable getAccountsVariable() { + return new Variable("accounts", DataTransferModel.typeMap); + } + + private Term getCreateAccountTerm() { + Symbol createAccount = new Symbol("createAccount", 4); + Variable accountId = new Variable("accountId", DataTransferModel.typeInt); + Variable username = new Variable("username", DataTransferModel.typeString); + Variable email = new Variable("email", DataTransferModel.typeString); + Variable password = new Variable("password", DataTransferModel.typeString); + Term term = new Term(createAccount); + term.addChild(accountId); + term.addChild(username); + term.addChild(email); + term.addChild(password); + return term; + } + + private Term getInsertTerm() { + Variable accounts = new Variable("accounts"); + Variable accountId = new Variable("accountId"); + JsonTerm jsonBody = new JsonTerm(); + Variable username = new Variable("username"); + Variable email = new Variable("email"); + Variable password = new Variable("password"); + jsonBody.addMember("username", username); + jsonBody.addMember("email", email); + jsonBody.addMember("password", password); + Symbol insert = new Symbol("insert", 3); + Term term = new Term(insert); + term.addChild(accounts); + term.addChild(accountId); + term.addChild(jsonBody); + return term; + } +}