-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #259 from MarkusAmshove/natparse/parse-input
Partially parse INPUT statements
- Loading branch information
Showing
5 changed files
with
306 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
libs/natparse/src/main/java/org/amshove/natparse/natural/IInputStatementNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.amshove.natparse.natural; | ||
|
||
import org.amshove.natparse.ReadOnlyList; | ||
|
||
public interface IInputStatementNode extends IStatementNode | ||
{ | ||
ReadOnlyList<IOperandNode> operands(); | ||
} |
30 changes: 30 additions & 0 deletions
30
libs/natparse/src/main/java/org/amshove/natparse/parsing/InputStatementNode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.amshove.natparse.parsing; | ||
|
||
import org.amshove.natparse.ReadOnlyList; | ||
import org.amshove.natparse.natural.IInputStatementNode; | ||
import org.amshove.natparse.natural.IOperandNode; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
class InputStatementNode extends StatementNode implements IInputStatementNode | ||
{ | ||
private final List<IOperandNode> operands = new ArrayList<>(); | ||
|
||
@Override | ||
public ReadOnlyList<IOperandNode> operands() | ||
{ | ||
return ReadOnlyList.from(operands); | ||
} | ||
|
||
void addOperand(IOperandNode operand) | ||
{ | ||
if (operand == null) | ||
{ | ||
// stuff like tab setting, line skip etc. | ||
return; | ||
} | ||
|
||
operands.add(operand); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
...se/src/test/java/org/amshove/natparse/parsing/statements/InputStatementParsingShould.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package org.amshove.natparse.parsing.statements; | ||
|
||
import org.amshove.natparse.natural.IInputStatementNode; | ||
import org.amshove.natparse.natural.ILiteralNode; | ||
import org.amshove.natparse.natural.ITokenNode; | ||
import org.amshove.natparse.natural.IVariableReferenceNode; | ||
import org.amshove.natparse.parsing.StatementParseTest; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; | ||
|
||
class InputStatementParsingShould extends StatementParseTest | ||
{ | ||
@Test | ||
void parseASimpleInput() | ||
{ | ||
var input = assertParsesSingleStatement("INPUT #VAR", IInputStatementNode.class); | ||
assertNodeOperand(input, 0, IVariableReferenceNode.class, "#VAR"); | ||
} | ||
|
||
@Test | ||
void parseASimpleInputWithMultipleOperands() | ||
{ | ||
var input = assertParsesSingleStatement("INPUT #VAR 'Hi' #VAR2", IInputStatementNode.class); | ||
assertNodeOperand(input, 0, IVariableReferenceNode.class, "#VAR"); | ||
assertNodeOperand(input, 1, ILiteralNode.class, "'Hi'"); | ||
assertNodeOperand(input, 2, IVariableReferenceNode.class, "#VAR2"); | ||
} | ||
|
||
@Test | ||
void parseAInputWithWindow() | ||
{ | ||
assertParsesSingleStatement("INPUT WINDOW='window' 'Hi'", IInputStatementNode.class); | ||
} | ||
|
||
@Test | ||
void parseInputWithNoErase() | ||
{ | ||
assertParsesSingleStatement("INPUT WINDOW='window' NO ERASE 'Hi'", IInputStatementNode.class); | ||
} | ||
|
||
@Test | ||
void consumeStatementAttributes() | ||
{ | ||
assertParsesSingleStatement("INPUT (AD=IO) 'Hi'", IInputStatementNode.class); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = | ||
{ | ||
"WITH TEXT", "TEXT" | ||
}) | ||
void consumeWithText(String permutation) | ||
{ | ||
var input = assertParsesSingleStatement("INPUT %s *MSG-INFO.##MSG-NR,#VAR2 'HI'".formatted(permutation), IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(1); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'HI'"); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = | ||
{ | ||
"MARK POSITION 3 IN FIELD #NUMBER", "MARK 3", "MARK #NUMBER", "MARK *#NUMBER" | ||
}) | ||
void consumeMark(String permutation) | ||
{ | ||
var input = assertParsesSingleStatement("INPUT %s 'HI'".formatted(permutation), IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(1); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'HI'"); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = | ||
{ | ||
"AND SOUND ALARM", "AND ALARM", "SOUND ALARM", "ALARM" | ||
}) | ||
void consumeAlarm(String permutation) | ||
{ | ||
var input = assertParsesSingleStatement("INPUT %s 'HI'".formatted(permutation), IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(1); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'HI'"); | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(strings = | ||
{ | ||
"USING MAP", "MAP" | ||
}) | ||
void consumeUsingMap(String permutation) | ||
{ | ||
var input = assertParsesSingleStatement("INPUT %s 'Map' 'HI'".formatted(permutation), IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(1); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'HI'"); | ||
} | ||
|
||
@Test | ||
void consumeUsingMapWithoutParameter() | ||
{ | ||
var input = assertParsesSingleStatement("INPUT USING MAP 'Map' NO PARAMETER", IInputStatementNode.class); | ||
assertThat(input.operands()).isEmpty(); | ||
} | ||
|
||
@Test | ||
void consumeInputsWithPositions() | ||
{ | ||
var input = assertParsesSingleStatement("INPUT 'Hi' 10/15 'Ho' 20/20 #VAR", IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(3); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'Hi'"); | ||
assertNodeOperand(input, 1, ILiteralNode.class, "'Ho'"); | ||
assertNodeOperand(input, 2, IVariableReferenceNode.class, "#VAR"); | ||
} | ||
|
||
@Test | ||
void consumeTabsAndSkips() | ||
{ | ||
var input = assertParsesSingleStatement("INPUT 'Hi' / 'Ho' 5T #VAR", IInputStatementNode.class); | ||
assertThat(input.operands()).hasSize(3); | ||
assertNodeOperand(input, 0, ILiteralNode.class, "'Hi'"); | ||
assertNodeOperand(input, 1, ILiteralNode.class, "'Ho'"); | ||
assertNodeOperand(input, 2, IVariableReferenceNode.class, "#VAR"); | ||
} | ||
|
||
private void assertNodeOperand(IInputStatementNode input, int index, Class<? extends ITokenNode> operandType, String source) | ||
{ | ||
assertThat( | ||
assertNodeType(input.operands().get(index), operandType) | ||
.token().source() | ||
).isEqualTo(source); | ||
} | ||
} |