Skip to content

Commit 9e90253

Browse files
committed
[Java.Interop.Tools.JavaSource] Java SE 13 Grammar
1 parent 80b4667 commit 9e90253

File tree

13 files changed

+837
-0
lines changed

13 files changed

+837
-0
lines changed

src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<ProjectGuid>{5C0B3562-8DA0-4726-9762-75B9709ED6B7}</ProjectGuid>
66
<AssemblyTitle>Java.Interop.Tools.JavaSource</AssemblyTitle>
7+
<LangVersion>8.0</LangVersion>
78
<Company>Microsoft Corporation</Company>
89
<Copyright>Microsoft Corporation</Copyright>
910
<AssemblyVersion>0.1.0.0</AssemblyVersion>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#nullable enable
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Linq;
7+
using System.Text;
8+
9+
using Irony.Ast;
10+
using Irony.Parsing;
11+
12+
namespace Java.Interop.Tools.JavaSource {
13+
14+
public static class IronyHelpers {
15+
16+
public static void MakeStarRule (this NonTerminal star, Grammar grammar, BnfTerm delimiter, BnfTerm of)
17+
{
18+
star.Rule = grammar.MakeStarRule (star, delimiter, of);
19+
}
20+
21+
public static void MakeStarRule (this NonTerminal star, Grammar grammar, BnfTerm of)
22+
{
23+
star.Rule = grammar.MakeStarRule (star, of);
24+
}
25+
26+
public static void FlattenChildNodes (AstContext context, ParseTreeNode parseNode)
27+
{
28+
parseNode.AstNode = string.Join ("", parseNode.ChildNodes.Select (cn => cn.AstNode));
29+
}
30+
31+
public static void UseFirstChildAstNode (AstContext context, ParseTreeNode parseNode)
32+
{
33+
foreach (var child in parseNode.ChildNodes) {
34+
if (child.AstNode != null) {
35+
parseNode.AstNode = child.AstNode;
36+
return;
37+
}
38+
}
39+
}
40+
41+
public static AstNodeCreator WithCreator (Func<IList<string?>, string> creator)
42+
{
43+
AstNodeCreator c = (AstContext context, ParseTreeNode parseNode) => {
44+
var childValues = parseNode.ChildNodes.Select (cn => cn.AstNode?.ToString ())
45+
.ToList ();
46+
parseNode.AstNode = creator (childValues);
47+
};
48+
return c;
49+
}
50+
}
51+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
7+
using Irony.Ast;
8+
using Irony.Parsing;
9+
10+
using Xamarin.Android.Tools.ApiXmlAdjuster;
11+
12+
namespace Java.Interop.Tools.JavaSource {
13+
14+
using static IronyHelpers;
15+
16+
partial class JavaSE13Grammar {
17+
// §8 Classes: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html
18+
public class ClassesBnfTerms {
19+
internal void CreateRules (JavaSE13Grammar grammar)
20+
{
21+
ClassDeclaration.Rule = NormalClassDeclaration | EnumClassDeclaration;
22+
NormalClassDeclaration.Rule = ClassModifier.Q () + "class" + grammar.LexicalTerms.TypeIdentifier + TypeParameters.Q () +
23+
Superclass.Q () + Superinterfaces.Q () +
24+
ClassBody;
25+
26+
ClassModifier.Rule = /* TODO: Annotations */ grammar.ToTerm ("public")
27+
| "protected"
28+
| "private"
29+
| "abstract"
30+
| "static"
31+
| "final"
32+
| "strictfp";
33+
34+
var ClassType = new NonTerminal ("ClassType", FlattenChildNodes);
35+
Superclass.Rule = "extends" + ClassType;
36+
}
37+
38+
internal void OnGrammarDataConstructed (LanguageData language)
39+
{
40+
}
41+
42+
// §8.1 Class Declrations: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1
43+
public readonly NonTerminal ClassDeclaration = new NonTerminal (nameof (ClassDeclaration), FlattenChildNodes);
44+
public readonly NonTerminal NormalClassDeclaration = new NonTerminal (nameof (NormalClassDeclaration), FlattenChildNodes);
45+
public readonly NonTerminal EnumClassDeclaration = new NonTerminal (nameof (EnumClassDeclaration), FlattenChildNodes);
46+
47+
// §8.1.1 Class Modifiers: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1.1
48+
public readonly NonTerminal ClassModifier = new NonTerminal (nameof (ClassModifier), FlattenChildNodes);
49+
50+
// §8.1.2 Generic Classes and Type Parameters: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1.2
51+
public readonly NonTerminal TypeParameters = new NonTerminal (nameof (TypeParameters), FlattenChildNodes);
52+
53+
// §8.1.4 Superclasses and Subclasses: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1.4
54+
public readonly NonTerminal Superclass = new NonTerminal (nameof (Superclass), FlattenChildNodes);
55+
56+
// §8.1.5 Superinterfaces: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1.5
57+
public readonly NonTerminal Superinterfaces = new NonTerminal (nameof (Superinterfaces), FlattenChildNodes);
58+
public readonly NonTerminal InterfaceTypeList = new NonTerminal (nameof (InterfaceTypeList), FlattenChildNodes);
59+
60+
// §8.1.6 Class Body and Member Declarations: https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.1.6
61+
public readonly NonTerminal ClassBody = new NonTerminal (nameof (ClassBody), FlattenChildNodes);
62+
public readonly NonTerminal ClassBodyDeclaration = new NonTerminal (nameof (ClassBodyDeclaration), FlattenChildNodes);
63+
public readonly NonTerminal InstanceInitializer = new NonTerminal (nameof (InstanceInitializer), FlattenChildNodes);
64+
public readonly NonTerminal StaticInitializer = new NonTerminal (nameof (StaticInitializer), FlattenChildNodes);
65+
public readonly NonTerminal ConstructorDeclaration = new NonTerminal (nameof (ConstructorDeclaration), FlattenChildNodes);
66+
public readonly NonTerminal FieldDeclaration = new NonTerminal (nameof (FieldDeclaration), FlattenChildNodes);
67+
public readonly NonTerminal MethodDeclaration = new NonTerminal (nameof (MethodDeclaration), FlattenChildNodes);
68+
}
69+
}
70+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
7+
using Irony.Ast;
8+
using Irony.Parsing;
9+
10+
using Xamarin.Android.Tools.ApiXmlAdjuster;
11+
12+
namespace Java.Interop.Tools.JavaSource {
13+
14+
using static IronyHelpers;
15+
16+
partial class JavaSE13Grammar {
17+
// §15 Expressions: https://docs.oracle.com/javase/specs/jls/se13/html/jls-15.html
18+
public class ExpressionsBnfTerms {
19+
internal void CreateRules (JavaSE13Grammar grammar)
20+
{
21+
Expression.Rule = LambdaExpresssion
22+
| AssignmentExpression;
23+
24+
#if false
25+
PrimaryNoNewArray = new NonTerminal (nameof (PrimaryNoNewArray)) {
26+
Rule = LexicalTerms.Literal
27+
| ClassLiteral
28+
| grammar.ToTerm ("this")
29+
| NameTerms.TypeName + grammar.ToTerm (".") + grammar.ToTerm ("this")
30+
| grammar.ToTerm ("(") + Expression
31+
}
32+
Primary = new NonTerminal (nameof (Primary)) {
33+
Rule = PrimaryNoNewArray | ArrayCreationExpression,
34+
};
35+
#endif
36+
}
37+
38+
// §15.2 Forms of Expressions: https://docs.oracle.com/javase/specs/jls/se13/html/jls-15.html#jls-15.2
39+
public readonly NonTerminal Expression = new NonTerminal (nameof (Expression), FlattenChildNodes);
40+
public readonly NonTerminal LambdaExpresssion = new NonTerminal (nameof (LambdaExpresssion), FlattenChildNodes);
41+
public readonly NonTerminal AssignmentExpression = new NonTerminal (nameof (AssignmentExpression), FlattenChildNodes);
42+
}
43+
}
44+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
7+
using Irony.Ast;
8+
using Irony.Parsing;
9+
10+
using Xamarin.Android.Tools.ApiXmlAdjuster;
11+
12+
namespace Java.Interop.Tools.JavaSource {
13+
14+
using static IronyHelpers;
15+
16+
// https://docs.oracle.com/javase/specs/jls/se13/html/jls-19.html
17+
// https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html
18+
partial class JavaSE13Grammar {
19+
public class LexicalBnfTerms {
20+
internal void CreateRules (JavaSE13Grammar grammar)
21+
{
22+
TypeIdentifier.Rule = Identifier;
23+
BooleanLiteral.Rule = grammar.ToTerm ("true")
24+
| grammar.ToTerm ("false");
25+
IntegerLiteral.Rule = DecimalIntegerLiteral
26+
| HexIntegerLiteral
27+
| OctalIntegerLiteral
28+
| BinaryIntegerLiteral;
29+
FloatingPointLiteral.Rule = DecimalFloatingPointLiteral
30+
| HexadecimalFloatingPointLiteral;
31+
Literal.Rule = IntegerLiteral
32+
| FloatingPointLiteral
33+
| BooleanLiteral
34+
| CharacterLiteral
35+
| StringLiteral
36+
| NullLiteral;
37+
38+
Identifier.AstConfig.NodeCreator = (context, parseNode) => {
39+
parseNode.AstNode = parseNode.Token.Value;
40+
};
41+
DotIdentifier.Rule = "." + Identifier;
42+
DotIdentifiers.MakeStarRule (grammar, DotIdentifier);
43+
}
44+
45+
internal void OnGrammarDataConstructed (LanguageData language)
46+
{
47+
NullLiteral.Init (language.GrammarData);
48+
}
49+
50+
// §3.7 Comments: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.7
51+
public readonly Terminal EndOfLineComment = new CommentTerminal ("EndOfLineComment", "//", "\r", "\n", "\u2085", "\u2028", "\u2029");
52+
public readonly Terminal TraditionalComment = new CommentTerminal ("TraditionalComment", "/*", "*/");
53+
public readonly Terminal JavaDocComment = new CommentTerminal ("JavaDocComment", "/**", "*/");
54+
55+
// § 3.8 Identifiers: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.8
56+
// https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Character.html#isJavaIdentifierStart(char)
57+
const string JavaIdentifierStart = "[" +
58+
@"\p{L}" + // Letters
59+
@"\p{Nl}" + // LETTER_NUMBER
60+
@"\p{Sc}" + // Currency symbols
61+
@"\p{Pc}" + // Connecting punctuation
62+
"]";
63+
64+
// https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Character.html#isJavaIdentifierPart(char)
65+
const string JavaIdentifierPart = "[" +
66+
@"\p{L}" + // Letters
67+
@"\p{Sc}" + // Currency symbols
68+
@"\p{Pc}" + // Connecting punctuation
69+
@"\d" + // Digit
70+
// @"" + // numeric letter?
71+
@"\p{Mc}" + // Combining mark
72+
@"\p{Mn}" + // Non-spacing Mark
73+
// @"" + // isIdentifierIgnorable?
74+
"]";
75+
76+
public readonly Terminal Identifier = new RegexBasedTerminal (nameof (Identifier), JavaIdentifierStart + JavaIdentifierPart + "*");
77+
public readonly NonTerminal TypeIdentifier = new NonTerminal (nameof (TypeIdentifier));
78+
79+
public readonly NonTerminal DotIdentifier = new NonTerminal (".Identifier", WithCreator (v => "." + string.Join ("", v)));
80+
public readonly NonTerminal DotIdentifiers = new NonTerminal ("(.Identifier)*", FlattenChildNodes);
81+
82+
// §3.10 Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10
83+
public readonly NonTerminal Literal = new NonTerminal (nameof (Literal));
84+
85+
// §3.10.1 Integer Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.1
86+
const string Digits = "(0|[1-9])([_0-9]*[0-9])?";
87+
88+
public readonly NonTerminal IntegerLiteral = new NonTerminal (nameof (IntegerLiteral));
89+
public readonly Terminal DecimalIntegerLiteral = new RegexBasedTerminal (nameof (DecimalIntegerLiteral), $"({Digits})([lL])?");
90+
const string HexDigit = "[0-9A-Fa-f]";
91+
const string HexDigitOrUnderscore = "[0-9A-Fa-f_]";
92+
const string HexDigitsAndUnderscores = HexDigitOrUnderscore + "+";
93+
const string HexDigits = HexDigit + "(" + HexDigitOrUnderscore + "*" + HexDigit + ")?";
94+
const string HexNumeral = "0[Xx]" + HexDigits;
95+
public readonly Terminal HexIntegerLiteral = new RegexBasedTerminal (nameof (HexIntegerLiteral), $@"{HexNumeral}([lL])?");
96+
public readonly Terminal OctalIntegerLiteral = new RegexBasedTerminal (nameof (OctalIntegerLiteral), @"0[0-7]([0-7_]*[0-7])?");
97+
public readonly Terminal BinaryIntegerLiteral = new RegexBasedTerminal (nameof (BinaryIntegerLiteral), @"0[Bb][01]([01_]*[01])?");
98+
99+
// §3.10.2 Floating-Point Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.2
100+
public readonly NonTerminal FloatingPointLiteral = new NonTerminal (nameof (FloatingPointLiteral));
101+
const string FloatTypeSuffix = "[fFdD]";
102+
const string SignedInteger = "[+-]?" + Digits;
103+
const string ExponentIndicator = "[eE]";
104+
const string ExponentPart = ExponentIndicator + SignedInteger;
105+
public readonly Terminal DecimalFloatingPointLiteral = new RegexBasedTerminal (nameof (DecimalFloatingPointLiteral), "(" +
106+
$@"{Digits}\.({Digits})?({ExponentPart})?({FloatTypeSuffix})?" +
107+
"|" +
108+
$@"\.{Digits}({ExponentPart})?({FloatTypeSuffix})?" +
109+
"|" +
110+
$@"{Digits}{ExponentPart}({FloatTypeSuffix})?" +
111+
"|" +
112+
$@"{Digits}({ExponentPart})?{FloatTypeSuffix}" +
113+
")");
114+
const string HexSignficand = "(" +
115+
HexNumeral + @"\.?" +
116+
"|" +
117+
"0[Xx](" + HexDigits + @")?\." + HexDigits + ")" +
118+
")";
119+
const string BinaryExponentIndicator = "[pP]";
120+
const string BinaryExponent = BinaryExponentIndicator + SignedInteger;
121+
public readonly Terminal HexadecimalFloatingPointLiteral = new RegexBasedTerminal (nameof (HexadecimalFloatingPointLiteral),
122+
$"({HexSignficand}{BinaryExponent}{FloatTypeSuffix}?");
123+
124+
// §3.10.3 Boolean Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.3
125+
public readonly NonTerminal BooleanLiteral = new NonTerminal (nameof (BooleanLiteral));
126+
127+
// §3.10.4 Character Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.4
128+
const string EscapeSequence = @"(\b|\t|\n|\f|\r|\""|\'|\\|\[0-3][0-7][0-7]|\[0-7][0-7]|\[0-7])";
129+
public readonly Terminal CharacterLiteral = new StringLiteral (nameof (CharacterLiteral), startEndSymbol: "'", options: StringOptions.IsChar | StringOptions.AllowsAllEscapes);
130+
#if false
131+
public readonly Terminal CharacterLiteral = new RegexBasedTerminal (nameof (CharacterLiteral), "'" +
132+
"(" +
133+
"[^\\'\u000a\u000d]" + // SingleCharacter
134+
"|" +
135+
EscapeSequence + // EscapeSequence
136+
")'");
137+
#endif
138+
139+
// §3.10.5 String Literals: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.5
140+
public readonly Terminal StringLiteral = new StringLiteral (nameof (StringLiteral), "\"", StringOptions.AllowsAllEscapes);
141+
#if false
142+
public readonly Terminal StringLiteral = new RegexBasedTerminal (nameof (StringLiteral), "\"" +
143+
"(" +
144+
"[^\\\"\u000a\u000d]" + // StringCharacter
145+
"|" +
146+
EscapeSequence +
147+
")*\"");
148+
#endif
149+
150+
// §3.10.7 The Null Literal: https://docs.oracle.com/javase/specs/jls/se13/html/jls-3.html#jls-3.10.7
151+
public readonly Terminal NullLiteral = new KeyTerm ("null", "null");
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)