Skip to content

Commit 3047e2a

Browse files
committed
Set up basic ANTLR grammar for Fix
Generate Java sources after edit: `./gradlew generateGrammarSource` See metafacture/metafacture-fix#298
1 parent e10dc74 commit 3047e2a

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2024 Fabian Steeg, hbz
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
grammar Fix;
18+
19+
options {
20+
language = Java;
21+
output = AST;
22+
ASTLabelType = CommonTree;
23+
}
24+
25+
@header {
26+
package org.metafacture.fix.parser;
27+
}
28+
29+
@lexer::header {
30+
package org.metafacture.fix.parser;
31+
}
32+
33+
fix : expression*;
34+
35+
expression : (doExpr | unless | ifExpr | methodCall | COMMENT) WS*;
36+
37+
methodCall : ID '(' (ID|option) (',' (ID|option))* ')';
38+
39+
doExpr : 'do' methodCall expression* 'end';
40+
41+
unless : 'unless' methodCall expression* 'end';
42+
43+
ifExpr : 'if' methodCall expression* elsIf* elseExpr? 'end';
44+
45+
elsIf : 'elsif' methodCall expression*;
46+
47+
elseExpr : 'else' expression*;
48+
49+
option : ID ':' ID;
50+
51+
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
52+
53+
COMMENT : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;};
54+
55+
WS : (' '| '\t'| '\r'| '\n') {$channel=HIDDEN;};
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2024 Fabian Steeg, hbz
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.metafacture.fix;
18+
19+
import static org.junit.Assert.assertEquals;
20+
21+
import org.metafacture.fix.parser.FixLexer;
22+
import org.metafacture.fix.parser.FixParser;
23+
24+
import org.antlr.runtime.ANTLRInputStream;
25+
import org.antlr.runtime.CommonTokenStream;
26+
import org.antlr.runtime.RecognitionException;
27+
import org.antlr.runtime.tree.Tree;
28+
import org.junit.Test;
29+
30+
import java.io.ByteArrayInputStream;
31+
import java.io.IOException;
32+
import java.nio.charset.StandardCharsets;
33+
34+
/**
35+
* Tests for the Fix grammar.
36+
*
37+
* @author Fabian Steeg
38+
*/
39+
public final class FixGrammarTest {
40+
41+
@Test
42+
public void parseSimpleFix() {
43+
assertEquals("add_field ( test )", parseToString("add_field(test)"));
44+
}
45+
46+
@Test
47+
public void parseSimpleFixWithOption() {
48+
assertEquals("add_field ( test1 , option : test2 )", parseToString("add_field(test1,option:test2)"));
49+
}
50+
51+
@Test
52+
public void parseFixWithIf() {
53+
assertEquals("if some ( test1 ) add ( something ) elsif some ( test2 ) add ( somethingElse , opt : one ) else add ( anotherThing , opt : two ) end",
54+
parseToString(
55+
"if some(test1)",
56+
" add(something)",
57+
"elsif some(test2)",
58+
" add(somethingElse, opt: one)",
59+
"else",
60+
" add(anotherThing, opt: two)",
61+
" # comment",
62+
"end"));
63+
}
64+
65+
@Test
66+
public void parseError() {
67+
assertEquals("<unexpected: [@3,14:14='<EOF>',<-1>,1:14], resync=add_field(> <mismatched token: [@3,14:14='<EOF>',<-1>,1:14], resync=test>",
68+
parseToString("add_field(test"));
69+
}
70+
71+
private String parseToString(final String... fixLines) {
72+
try {
73+
final ByteArrayInputStream fixInput = createInputStream(String.join("\n", fixLines));
74+
final FixLexer lexer = new FixLexer(new ANTLRInputStream(fixInput));
75+
final FixParser parser = new FixParser(new CommonTokenStream(lexer));
76+
return ((Tree) parser.fix().getTree()).toStringTree();
77+
} catch (IOException | RecognitionException e) {
78+
e.printStackTrace();
79+
return null;
80+
}
81+
}
82+
83+
private ByteArrayInputStream createInputStream(final String string) {
84+
return new ByteArrayInputStream(string.getBytes(StandardCharsets.UTF_8));
85+
}
86+
87+
}

0 commit comments

Comments
 (0)