Rendering the grammar for Confluence
This commit is contained in:
Generated
+8
@@ -10,6 +10,14 @@
|
|||||||
<maximumStackSize value="2" />
|
<maximumStackSize value="2" />
|
||||||
<properties />
|
<properties />
|
||||||
</buildFile>
|
</buildFile>
|
||||||
|
<buildFile url="file://$PROJECT_DIR$/grammar/buildGrammarLexer.xml">
|
||||||
|
<additionalClassPath />
|
||||||
|
<antReference projectDefault="true" />
|
||||||
|
<customJdkName value="" />
|
||||||
|
<maximumHeapSize value="128" />
|
||||||
|
<maximumStackSize value="2" />
|
||||||
|
<properties />
|
||||||
|
</buildFile>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<project name="GrammarLexer" default="lexer">
|
||||||
|
<property name="home" value="${basedir}"/>
|
||||||
|
<property file="${home}/../idea/idea.properties"/>
|
||||||
|
|
||||||
|
<property name="flex.base" value="${idea.home}/tools/lexer/jflex-1.4"/>
|
||||||
|
<property name="out.dir" value="${basedir}/tmpout"/>
|
||||||
|
|
||||||
|
<macrodef name="flex">
|
||||||
|
<attribute name="flexfile"/>
|
||||||
|
<attribute name="destdir"/>
|
||||||
|
<attribute name="skeleton" default="${idea.home}/tools/lexer/idea-flex.skeleton"/>
|
||||||
|
<sequential>
|
||||||
|
<delete dir="${out.dir}"/>
|
||||||
|
<mkdir dir="${out.dir}"/>
|
||||||
|
<java classname="JFlex.Main"
|
||||||
|
jvmargs="-Xmx512M"
|
||||||
|
fork="true"
|
||||||
|
failonerror="true">
|
||||||
|
<arg value="-sliceandcharat"/>
|
||||||
|
<arg value="-skel"/>
|
||||||
|
<arg value="@{skeleton}"/>
|
||||||
|
<arg value="-d"/>
|
||||||
|
<arg value="${out.dir}"/>
|
||||||
|
<arg value="@{flexfile}"/>
|
||||||
|
<classpath>
|
||||||
|
<pathelement location="${flex.base}/lib/JFlex.jar"/>
|
||||||
|
</classpath>
|
||||||
|
</java>
|
||||||
|
<move todir="@{destdir}">
|
||||||
|
<fileset dir="${out.dir}">
|
||||||
|
<include name="*.java"/>
|
||||||
|
</fileset>
|
||||||
|
</move>
|
||||||
|
<delete dir="${out.dir}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="lexer">
|
||||||
|
<echo message="${flex.base}"/>
|
||||||
|
<flex flexfile="${home}/src/org/jetbrains/jet/grammar/Grammar.flex"
|
||||||
|
destdir="${home}//src/org/jetbrains/jet/grammar/"/>
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
@@ -7,6 +7,15 @@
|
|||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library>
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MODULE_DIR$/../../idea/idea.app/lib/util.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h2. Annotations
|
||||||
|
*/
|
||||||
|
|
||||||
attributes
|
attributes
|
||||||
: attributeAnnotation*
|
: attributeAnnotation*
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h2. Classes
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : Some)
|
internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : Some)
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h3. Class members
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class Example(a : Foo, i : Int) : Bar(i), Some {
|
class Example(a : Foo, i : Int) : Bar(i), Some {
|
||||||
// constrtuctors:
|
// constrtuctors:
|
||||||
@@ -37,20 +41,24 @@ memberDeclaration
|
|||||||
: function
|
: function
|
||||||
: property
|
: property
|
||||||
: class
|
: class
|
||||||
: extension
|
: extension §
|
||||||
: typedef
|
: typedef
|
||||||
: anonymousInitializer
|
: anonymousInitializer
|
||||||
;
|
;
|
||||||
|
|
||||||
|
anonymousInitializer
|
||||||
|
: block
|
||||||
|
;
|
||||||
|
|
||||||
classObject
|
classObject
|
||||||
: modifiers "class" object
|
: modifiers "class" object
|
||||||
;
|
;
|
||||||
|
|
||||||
constructor
|
constructor
|
||||||
: modifiers "this" functionParameters (":" initializer{","}) block?
|
: modifiers "this" valueParameters (":" initializer{","}) block?
|
||||||
;
|
;
|
||||||
|
|
||||||
functionParameters
|
valueParameters
|
||||||
: "(" functionParameter{","}? ")" // default values
|
: "(" functionParameter{","}? ")" // default values
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -71,7 +79,7 @@ function
|
|||||||
: modifiers "fun" typeParameters?
|
: modifiers "fun" typeParameters?
|
||||||
(type "." | attributes/*for receiver type*/)?
|
(type "." | attributes/*for receiver type*/)?
|
||||||
SimpleName
|
SimpleName
|
||||||
typeParameters? functionParameters (":" type)?
|
typeParameters? valueParameters (":" type)?
|
||||||
functionBody?
|
functionBody?
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h3. Control structures
|
||||||
|
*/
|
||||||
|
|
||||||
if
|
if
|
||||||
: "if" "(" expression ")" expression SEMI? ("else" expression)?
|
: "if" "(" expression ")" expression SEMI? ("else" expression)?
|
||||||
;
|
;
|
||||||
@@ -21,7 +25,7 @@ loop
|
|||||||
;
|
;
|
||||||
|
|
||||||
for
|
for
|
||||||
: "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
|
: "for" "(" attributes ("val" | "var")? SimpleName (":" type)? "in" expression ")" expression
|
||||||
;
|
;
|
||||||
|
|
||||||
while
|
while
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
/**
|
||||||
|
h3. Enum classes
|
||||||
|
*/
|
||||||
|
|
||||||
enumClassBody
|
enumClassBody
|
||||||
: "{" enumEntry* "}"
|
: "{" enumEntry* "}"
|
||||||
;
|
;
|
||||||
|
|
||||||
enumEntry
|
enumEntry
|
||||||
: modifiers SimpleName typeParameters? primaryConstructorParameters? (":" initializer{","})? classBody?
|
: modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? classBody?
|
||||||
;
|
;
|
||||||
|
|||||||
+11
-10
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h2. Expressions
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Decreasing precedence:
|
Decreasing precedence:
|
||||||
memberAccessOperation
|
memberAccessOperation
|
||||||
@@ -108,7 +112,7 @@ literalConstant
|
|||||||
: StringWithTemplates
|
: StringWithTemplates
|
||||||
: NoEscapeString
|
: NoEscapeString
|
||||||
: IntegerLiteral
|
: IntegerLiteral
|
||||||
: LongLiteral
|
: HexadecimalLiteral
|
||||||
: CharacterLiteral
|
: CharacterLiteral
|
||||||
: FloatLiteral
|
: FloatLiteral
|
||||||
: "null"
|
: "null"
|
||||||
@@ -148,7 +152,7 @@ typeOperation
|
|||||||
: "as" : "as?" : ":"
|
: "as" : "as?" : ":"
|
||||||
;
|
;
|
||||||
|
|
||||||
isOPeration
|
isOperation
|
||||||
: "is" : "!is"
|
: "is" : "!is"
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -210,17 +214,14 @@ jump
|
|||||||
// yield ?
|
// yield ?
|
||||||
;
|
;
|
||||||
|
|
||||||
stringLiteral
|
// Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an expression in parentheses
|
||||||
: StringWithTemplates
|
// to put a tuple, write write ((e))
|
||||||
: NoEscapeString
|
tupleLiteral
|
||||||
;
|
|
||||||
|
|
||||||
tupleLiteral // Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an expression in parentheses
|
|
||||||
// to put a tuple, write write ((e))
|
|
||||||
: "(" ((SimpleName "=")? expression){","} ")"
|
: "(" ((SimpleName "=")? expression){","} ")"
|
||||||
;
|
;
|
||||||
|
|
||||||
functionLiteral // one can use "it" as a parameter name
|
// one can use "it" as a parameter name
|
||||||
|
functionLiteral
|
||||||
: "{" statements "}"
|
: "{" statements "}"
|
||||||
: "{" (type ".")? modifiers SimpleName "=>" statements "}"
|
: "{" (type ".")? modifiers SimpleName "=>" statements "}"
|
||||||
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" statements "}"
|
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" statements "}"
|
||||||
|
|||||||
+37
-10
@@ -1,15 +1,42 @@
|
|||||||
SimpleName : /*java identifier*/;
|
/**
|
||||||
FieldName : "$" SimpleName;
|
h1. Lexical structure
|
||||||
LabelName : "@" SimpleName;
|
*/
|
||||||
[helper] Digit : ["0".."9"];
|
|
||||||
IntegerLiteral : Digit+ "L"?
|
|
||||||
[helper] HexDigit : Digit | ["A"-"F", "a"-"f"];
|
|
||||||
HexadecimalLiteral : "0x" HexDigit+;
|
|
||||||
|
|
||||||
CharacterLiteral : /*character as in Java*/;
|
SimpleName
|
||||||
|
: <java identifier>;
|
||||||
|
FieldName
|
||||||
|
: "$" SimpleName;
|
||||||
|
LabelName
|
||||||
|
: "@" SimpleName;
|
||||||
|
|
||||||
StringWithTemplates : /*single-quoted string, $ can be escaped*/;
|
[helper]
|
||||||
NoEscapeString : /* """-quoted string */;
|
Digit
|
||||||
|
: ["0".."9"];
|
||||||
|
|
||||||
|
IntegerLiteral
|
||||||
|
: Digit+ "L"?
|
||||||
|
|
||||||
|
FloatLiteral
|
||||||
|
: <java double literal>;
|
||||||
|
|
||||||
|
[helper]
|
||||||
|
HexDigit
|
||||||
|
: Digit | ["A"-"F", "a"-"f"];
|
||||||
|
|
||||||
|
HexadecimalLiteral
|
||||||
|
: "0x" HexDigit+;
|
||||||
|
|
||||||
|
CharacterLiteral
|
||||||
|
: <character as in Java>;
|
||||||
|
|
||||||
|
StringWithTemplates
|
||||||
|
: <single-quoted string, $ can be escaped>;
|
||||||
|
|
||||||
|
NoEscapeString
|
||||||
|
: <"""-quoted string>;
|
||||||
|
|
||||||
|
SEMI
|
||||||
|
: <semicolon or newline>;
|
||||||
|
|
||||||
/* Symbols:
|
/* Symbols:
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h3. Modifiers
|
||||||
|
*/
|
||||||
|
|
||||||
modifiers
|
modifiers
|
||||||
: modifier*
|
: modifier*
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
h1. Notation
|
||||||
|
|
||||||
|
This section informally explains the grammar notation used below.
|
||||||
|
|
||||||
|
h2. Symbols and naming
|
||||||
|
|
||||||
|
_Terminal symbol_ names start with an uppercase letter, e.g. *SimpleName*
|
||||||
|
_Nonterminal symbol_ names start with lowercase letter, e.g. *jetFile*
|
||||||
|
Each _production_ starts with a colon (*:*)
|
||||||
|
_Symbol definitions_ may have many productions and are terminated by a semicolon (*;*)
|
||||||
|
Symbol definitions may be prepended with _attributes_, e.g. {{start}} attribute denotes a start symbol
|
||||||
|
|
||||||
|
h2. EBNF expressions
|
||||||
|
|
||||||
|
Operator {color:blue}*|*{color} denotes _alternative_
|
||||||
|
Operator {color:blue}*\**{color} denotes _iteration_ (zero or more)
|
||||||
|
Operator {color:blue}*+*{color} denotes _iteration_ (one or one)
|
||||||
|
Operator {color:blue}*?*{color} denotes _option_ (zero or one)
|
||||||
|
alpha{color:blue}*{*{color}beta{color:blue}*}*{color} denotes a nonempty _beta_-separated list of _alpha_s
|
||||||
|
*/
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Annotation extends Token {
|
||||||
|
public Annotation(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{{" + super.toString().replaceAll("\\[", "").replaceAll("\\]", "") + "}}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Comment extends Token {
|
||||||
|
public Comment(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "";//getText().toString().replaceAll("\\{", "\\\\{").replaceAll("\\[", "\\\\[").replaceAll("\\(", "\\\\(");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.ClipboardOwner;
|
||||||
|
import java.awt.datatransfer.StringSelection;
|
||||||
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ConfluenceHyperlinksGenerator {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
String grammarExtension = "grm";
|
||||||
|
File grammarDir = new File("grammar/src");
|
||||||
|
|
||||||
|
List<String> fileNamesInOrder = Arrays.asList(
|
||||||
|
"notation",
|
||||||
|
"lexical",
|
||||||
|
"toplevel",
|
||||||
|
"class",
|
||||||
|
"class_members",
|
||||||
|
"enum",
|
||||||
|
"types",
|
||||||
|
"modifiers",
|
||||||
|
"attributes",
|
||||||
|
"control",
|
||||||
|
"expressions",
|
||||||
|
"when"
|
||||||
|
);
|
||||||
|
|
||||||
|
StringBuilder allRules = new StringBuilder();
|
||||||
|
Set<File> used = new HashSet<File>();
|
||||||
|
for (String fileName : fileNamesInOrder) {
|
||||||
|
File file = new File(grammarDir, fileName + "." + grammarExtension);
|
||||||
|
used.add(file);
|
||||||
|
FileReader fileReader = new FileReader(file);
|
||||||
|
try {
|
||||||
|
int c;
|
||||||
|
while ((c = fileReader.read()) != -1) {
|
||||||
|
allRules.append((char) c);
|
||||||
|
}
|
||||||
|
allRules.append("\n");
|
||||||
|
allRules.append("\n");
|
||||||
|
} finally {
|
||||||
|
fileReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File file : grammarDir.listFiles()) {
|
||||||
|
if (file.getName().endsWith(grammarExtension)) {
|
||||||
|
if (!used.contains(file)) {
|
||||||
|
throw new IllegalStateException("Unused grammar file : " + file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
|
||||||
|
Pattern symbolReference = Pattern.compile("^\\w+$", Pattern.MULTILINE);
|
||||||
|
Matcher matcher = symbolReference.matcher(allRules);
|
||||||
|
int copiedUntil = 0;
|
||||||
|
while (matcher.find()) {
|
||||||
|
int start = matcher.start();
|
||||||
|
output.append(allRules.subSequence(copiedUntil, start));
|
||||||
|
|
||||||
|
String group = matcher.group();
|
||||||
|
output.append("&").append(group);
|
||||||
|
copiedUntil = matcher.end();
|
||||||
|
}
|
||||||
|
output.append(allRules.subSequence(copiedUntil, allRules.length()));
|
||||||
|
// System.out.println(output);
|
||||||
|
|
||||||
|
_GrammarLexer grammarLexer = new _GrammarLexer((Reader) null);
|
||||||
|
grammarLexer
|
||||||
|
.reset(output, 0, output.length(), 0);
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder("h1. Contents\n").append("{toc:style=disc|indent=20px}");
|
||||||
|
|
||||||
|
Set<String> declaredSymbols = new HashSet<String>();
|
||||||
|
Set<String> usedSymbols = new HashSet<String>();
|
||||||
|
List<Token> tokens = new ArrayList<Token>();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Token advance = grammarLexer.advance();
|
||||||
|
if (advance == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (advance instanceof Declaration) {
|
||||||
|
Declaration declaration = (Declaration) advance;
|
||||||
|
declaredSymbols.add(declaration.getName());
|
||||||
|
}
|
||||||
|
else if (advance instanceof Identifier) {
|
||||||
|
Identifier identifier = (Identifier) advance;
|
||||||
|
usedSymbols.add(identifier.getName());
|
||||||
|
}
|
||||||
|
tokens.add(advance);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Token token : tokens) {
|
||||||
|
if (token instanceof Declaration) {
|
||||||
|
Declaration declaration = (Declaration) token;
|
||||||
|
if (!usedSymbols.contains(declaration.getName())) {
|
||||||
|
result.append("(!) *Unused!* ");
|
||||||
|
System.out.println("Unused: " + token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (token instanceof Identifier) {
|
||||||
|
Identifier identifier = (Identifier) token;
|
||||||
|
if (!declaredSymbols.contains(identifier.getName())) {
|
||||||
|
result.append("(!) *Undeclared!* ");
|
||||||
|
System.out.println("Undeclared: " + token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
clipboard.setContents(new StringSelection(result.toString()), new ClipboardOwner() {
|
||||||
|
@Override
|
||||||
|
public void lostOwnership(Clipboard clipboard, Transferable contents) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<Integer> recordStarts(StringBuilder allRules, String regex) {
|
||||||
|
Pattern symbolDeclaration = Pattern.compile(regex, Pattern.MULTILINE);
|
||||||
|
Matcher matcher = symbolDeclaration.matcher(allRules);
|
||||||
|
Set<Integer> declarationStarts = new HashSet<Integer>();
|
||||||
|
while (matcher.find()) {
|
||||||
|
if (matcher.groupCount() > 0) {
|
||||||
|
declarationStarts.add(matcher.start(1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
declarationStarts.add(matcher.start());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return declarationStarts;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Declaration extends Token {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Declaration(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
name = text.toString().substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{anchor:" + name + "}*" + name + "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class DocComment extends Token {
|
||||||
|
public DocComment(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String s = super.toString();
|
||||||
|
return s.substring(3, s.length() - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/* It's an automatically generated code. Do not modify it. */
|
||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
//import com.intellij.lexer.*;
|
||||||
|
//import com.intellij.psi.*;
|
||||||
|
//import com.intellij.psi.tree.IElementType;
|
||||||
|
|
||||||
|
//import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
%unicode
|
||||||
|
%class _GrammarLexer
|
||||||
|
%function advance
|
||||||
|
%type Token
|
||||||
|
%eof{ return;
|
||||||
|
%eof}
|
||||||
|
|
||||||
|
DIGIT=[0-9]
|
||||||
|
HEX_DIGIT=[0-9A-Fa-f]
|
||||||
|
WHITE_SPACE_CHAR=[\ \n\t\f]
|
||||||
|
|
||||||
|
// TODO: prohibit '$' in identifiers?
|
||||||
|
PLAIN_IDENTIFIER=[:jletter:] [:jletterdigit:]*
|
||||||
|
// TODO: this one MUST allow everything accepted by the runtime
|
||||||
|
// TODO: Replace backticks by one backslash in the begining
|
||||||
|
ESCAPED_IDENTIFIER = `{PLAIN_IDENTIFIER}`
|
||||||
|
IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER}
|
||||||
|
DECLARATION_IDENTIFIER = "&" {PLAIN_IDENTIFIER}
|
||||||
|
FIELD_IDENTIFIER = \${IDENTIFIER}
|
||||||
|
LABEL_IDENTIFIER = \@{IDENTIFIER}
|
||||||
|
|
||||||
|
BLOCK_COMMENT=("/*"[^"*"]{COMMENT_TAIL})|"/*"
|
||||||
|
// TODO: Wiki markup for doc comments?
|
||||||
|
DOC_COMMENT="/*""*"+("/"|([^"/""*"]{COMMENT_TAIL}))?
|
||||||
|
COMMENT_TAIL=([^"*"]*("*"+[^"*""/"])?)*("*"+"/")?
|
||||||
|
EOL_COMMENT="/""/"[^\n]*
|
||||||
|
|
||||||
|
INTEGER_LITERAL={DECIMAL_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}|{BIN_INTEGER_LITERAL}
|
||||||
|
DECIMAL_INTEGER_LITERAL=(0|([1-9]({DIGIT})*))
|
||||||
|
HEX_INTEGER_LITERAL=0[Xx]({HEX_DIGIT})*
|
||||||
|
BIN_INTEGER_LITERAL=0[Bb]({DIGIT})*
|
||||||
|
LONG_LITERAL=({INTEGER_LITERAL})[Ll]
|
||||||
|
|
||||||
|
//FLOAT_LITERAL=(({FLOATING_POINT_LITERAL1})[Ff])|(({FLOATING_POINT_LITERAL2})[Ff])|(({FLOATING_POINT_LITERAL3})[Ff])|(({FLOATING_POINT_LITERAL4})[Ff])
|
||||||
|
//DOUBLE_LITERAL=(({FLOATING_POINT_LITERAL1})[Dd]?)|(({FLOATING_POINT_LITERAL2})[Dd]?)|(({FLOATING_POINT_LITERAL3})[Dd]?)|(({FLOATING_POINT_LITERAL4})[Dd])
|
||||||
|
DOUBLE_LITERAL={FLOATING_POINT_LITERAL1}|{FLOATING_POINT_LITERAL2}|{FLOATING_POINT_LITERAL3}|{FLOATING_POINT_LITERAL4}
|
||||||
|
FLOATING_POINT_LITERAL1=({DIGIT})+"."({DIGIT})+({EXPONENT_PART})?
|
||||||
|
FLOATING_POINT_LITERAL2="."({DIGIT})+({EXPONENT_PART})?
|
||||||
|
FLOATING_POINT_LITERAL3=({DIGIT})+({EXPONENT_PART})
|
||||||
|
FLOATING_POINT_LITERAL4=({DIGIT})+
|
||||||
|
EXPONENT_PART=[Ee]["+""-"]?({DIGIT})*
|
||||||
|
HEX_FLOAT_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Ff]
|
||||||
|
//HEX_DOUBLE_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Dd]?
|
||||||
|
HEX_DOUBLE_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}?
|
||||||
|
BINARY_EXPONENT=[Pp][+-]?{DIGIT}+
|
||||||
|
HEX_SIGNIFICAND={HEX_INTEGER_LITERAL}|0[Xx]{HEX_DIGIT}*\.{HEX_DIGIT}+
|
||||||
|
//HEX_SIGNIFICAND={HEX_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}\.|0[Xx]{HEX_DIGIT}*\.{HEX_DIGIT}+
|
||||||
|
|
||||||
|
CHARACTER_LITERAL="'"([^\\\'\n]|{ESCAPE_SEQUENCE})*("'"|\\)?
|
||||||
|
// TODO: introduce symbols (e.g. 'foo) as another way to write string literals
|
||||||
|
STRING_LITERAL=\"([^\\\"\n]|{ESCAPE_SEQUENCE})*(\"|\\)?
|
||||||
|
ANGLE_STRING_LITERAL=\<([^\\\>\n])*(\>|\\)?
|
||||||
|
ESCAPE_SEQUENCE=\\[^\n]
|
||||||
|
|
||||||
|
// ANY_ESCAPE_SEQUENCE = \\[^]
|
||||||
|
THREE_QUO = (\"\"\")
|
||||||
|
ONE_TWO_QUO = (\"[^\"]) | (\"\"[^\"])
|
||||||
|
QUO_STRING_CHAR = [^\"] | {ONE_TWO_QUO}
|
||||||
|
RAW_STRING_LITERAL = {THREE_QUO} {QUO_STRING_CHAR}* {THREE_QUO}?
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
<YYINITIAL> {BLOCK_COMMENT} { return new Comment(yytext()); }
|
||||||
|
<YYINITIAL> {DOC_COMMENT} { return new DocComment(yytext()); }
|
||||||
|
|
||||||
|
<YYINITIAL> ({WHITE_SPACE_CHAR})+ { return new WhiteSpace(yytext()); }
|
||||||
|
|
||||||
|
<YYINITIAL> {EOL_COMMENT} { return new Comment(yytext()); }
|
||||||
|
|
||||||
|
<YYINITIAL> {STRING_LITERAL} { return new StringToken(yytext()); }
|
||||||
|
<YYINITIAL> {ANGLE_STRING_LITERAL} { return new StringToken(yytext()); }
|
||||||
|
<YYINITIAL> {IDENTIFIER} { return new Identifier(yytext()); }
|
||||||
|
<YYINITIAL> "[" {IDENTIFIER} "]" { return new Annotation(yytext()); }
|
||||||
|
<YYINITIAL> {DECLARATION_IDENTIFIER} { return new Declaration(yytext()); }
|
||||||
|
|
||||||
|
<YYINITIAL> ":" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "{" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> "}" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> "[" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> "]" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> "(" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> ")" { return new SymbolToken("\\" + yytext()); }
|
||||||
|
<YYINITIAL> "*" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "+" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "?" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "|" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "-" { return new SymbolToken(yytext()); }
|
||||||
|
<YYINITIAL> "." { return new SymbolToken(yytext()); }
|
||||||
|
|
||||||
|
<YYINITIAL> . { return new Other(yytext()); }
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Identifier extends Token {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Identifier(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
name = text.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[#" + getText() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Other extends Token {
|
||||||
|
public Other(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class StringToken extends Token {
|
||||||
|
public StringToken(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{color:green}*{{" + getText().toString().replaceAll("\\{", "\\\\{").replaceAll("\\[", "\\\\[").replaceAll("!", "\\\\!") + "}}*{color}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class SymbolToken extends Token {
|
||||||
|
public SymbolToken(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{color:blue}*" + getText().toString().replaceAll("\\*", "\\\\*") + "*{color}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class Token {
|
||||||
|
private final CharSequence text;
|
||||||
|
|
||||||
|
public Token(CharSequence text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getText().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.jetbrains.jet.grammar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class WhiteSpace extends Token {
|
||||||
|
public WhiteSpace(CharSequence text) {
|
||||||
|
super(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString().replaceAll(" ", " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,15 @@
|
|||||||
[start] jetlFile
|
/**
|
||||||
|
h1. Syntax
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
[start]
|
||||||
|
jetFile
|
||||||
: preamble toplevelObject*
|
: preamble toplevelObject*
|
||||||
;
|
;
|
||||||
|
|
||||||
[start] script
|
[start]
|
||||||
|
script
|
||||||
: preamble expression*
|
: preamble expression*
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h2. Types
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Foo<Bar<X>, T, Object> // user type
|
Foo<Bar<X>, T, Object> // user type
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
/**
|
||||||
|
h3. Pattern matching
|
||||||
|
*/
|
||||||
|
|
||||||
when
|
when
|
||||||
: "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
|
: "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
|
||||||
whenEntry*
|
whenEntry*
|
||||||
@@ -35,7 +39,7 @@ pattern
|
|||||||
decomposerPattern
|
decomposerPattern
|
||||||
: type
|
: type
|
||||||
// TODO : typeParameters will be consumed by the expression
|
// TODO : typeParameters will be consumed by the expression
|
||||||
: elvisExpression typeParameters? '@' tuplePattern
|
: elvisExpression typeParameters? "@" tuplePattern
|
||||||
;
|
;
|
||||||
|
|
||||||
constantPattern
|
constantPattern
|
||||||
|
|||||||
Reference in New Issue
Block a user