Skip to content

Commit

Permalink
a textmate like language is generated but the match should be made in…
Browse files Browse the repository at this point in the history
…to a regex; this is also very barebones
  • Loading branch information
Naum-Tomov committed Dec 7, 2023
1 parent b04d7d1 commit 5626e6e
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 87 deletions.
2 changes: 2 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,8 @@ object vercors extends Module {
base() / "LexerAdaptor.java",
)

override def moduleDeps = Seq(hre)

object antlrGrammarParser extends parsers.GenModule {
override def base = T {
settings.src / "textMateGenerator" / "antlr4"
Expand Down
168 changes: 82 additions & 86 deletions src/parsers/antlr4/LangPVLLexer.g4
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
lexer grammar LangPVLLexer;
lexer grammar PVLLexer;
import SpecLexer;

channels {
EXPECTED_ERROR_CHANNEL
}

VAL_INLINE: 'inline';
VAL_ASSERT: 'assert';
VAL_PACKAGE: 'package';
VAL_INLINE: {"keyword.other";} 'inline';
VAL_ASSERT: {"keyword.other";} 'assert';
VAL_PACKAGE: {"meta.*"} 'package';

PAREN_OPEN: '(';
PAREN_CLOSE: ')';
Expand All @@ -24,87 +24,83 @@ POINT: '.';
COLON: ':';
SEMICOLON: ';';

QUESTION: '?';
EXCL: '!';
AND: '&&';
OR: '||';
BITOR: '|';
XOR: '^^';

GTE: '>=';
LTE: '<=';
ASSIGN: '=';
EQ: '==';
INEQ: '!=';

PLUS: '+';
MINUS: '-';
STAR: '*';
SLASH: '/';
PERCENT: '%';
INC: '++';
DEC: '--';
CONS: '::';

ENUM: 'enum';
CLASS: 'class';
SEQ_PROGRAM: 'seq_program';
SEQ_RUN: 'seq_run';
KERNEL: 'kernel';
BARRIER: 'barrier';
INVARIANT: 'invariant';
CONSTRUCTOR: 'constructor';
RUN: 'run';
THREAD: 'thread';
ENDPOINT: 'endpoint';

IF: 'if';
ELSE: 'else';
WHILE: 'while';
FOR: 'for';
GOTO: 'goto';
RETURN: 'return';
VEC: 'vec';
PAR: 'par';
PAR_AND: 'and';
PARALLEL: 'parallel';
SEQUENTIAL: 'sequential';
BLOCK: 'block';

LOCK: 'lock';
UNLOCK: 'unlock';
WAIT: 'wait';
NOTIFY: 'notify';
FORK: 'fork';
JOIN: 'join';

COMMUNICATE: 'communicate';

THIS: 'this';
NULL: 'null';
TRUE: 'true';
FALSE: 'false';
CURRENT_THREAD: 'current_thread';
CURRENT_THREAD_ESC: '\\current_thread';
OWNER: '\\owner';

GLOBAL: 'global';
LOCAL: 'local';
STATIC: 'static';
FINAL: 'final';
UNFOLDING_ESC: '\\unfolding';
UNFOLDING: 'unfolding';
IN_ESC: '\\in';
IN: 'in';
NEW: 'new';
ID: 'id';

BOOL: 'boolean';
VOID: 'void';
INT: 'int';
CHAR: 'char';
FLOAT32: 'float32';
FLOAT64: 'float64';
QUESTION: {"keyword.operator";} '?';
EXCL: {"keyword.operator";} '!';
AND: {"keyword.operator";} '&&';
OR: {"keyword.operator";} '||';
BITOR: {"keyword.operator";} '|';
XOR: {"keyword.operator";} '^^';

GTE: {"keyword.operator";} '>=';
LTE: {"keyword.operator";} '<=';
ASSIGN: {"keyword.operator";} '=';
EQ: {"keyword.operator";} '==';
INEQ: {"keyword.operator";} '!=';

PLUS: {"keyword.operator";} '+';
MINUS: {"keyword.operator";} '-';
STAR: {"keyword.operator";} '*';
SLASH: {"keyword.operator";} '/';
PERCENT: {"keyword.operator";} '%';
INC: {"keyword.operator";} '++';
DEC: {"keyword.operator";} '--';
CONS: {"keyword.operator";} '::';

ENUM: {"storage.type";} 'enum';
CLASS: {"storage.type";} 'class';
SEQ_PROGRAM: {"keyword.control.concurrency";} 'seq_program';
KERNEL: {"keyword.control.concurrency";} 'kernel';
BARRIER: {"keyword.control.concurrency";} 'barrier';
INVARIANT: {"keyword.control.concurrency";} 'invariant';
CONSTRUCTOR: {"variable.language";} 'constructor';
RUN: {"keyword.control.concurrency";} 'run';
THREAD: {"keyword.control.concurrency";} 'thread';

IF: {"keyword.control";} 'if';
ELSE: {"keyword.control";} 'else';
WHILE: {"keyword.control";} 'while';
FOR: {"keyword.control";} 'for';
GOTO: {"keyword.control";} 'goto';
RETURN: {"keyword.control";} 'return';
VEC: {"variable.language";} 'vec';
PAR: {"keyword.control.concurrency";} 'par';
PAR_AND: {"keyword.control.concurrency";} 'and';
PARALLEL: {"keyword.control.concurrency";} 'parallel';
SEQUENTIAL: {"keyword.control.concurrency";} 'sequential';
BLOCK: {"keyword.control";} 'block';

LOCK: {"keyword.control.concurrency";} 'lock';
UNLOCK: {"keyword.control.concurrency";} 'unlock';
WAIT: {"keyword.control.concurrency";} 'wait';
NOTIFY: {"keyword.control.concurrency";} 'notify';
FORK: {"keyword.control.concurrency";} 'fork';
JOIN: {"keyword.control.concurrency";} 'join';

THIS: {"variable.language";} 'this';
NULL: {"variable.language";} 'null';
TRUE: {"variable.language";} 'true';
FALSE: {"variable.language";} 'false';
CURRENT_THREAD: {"variable.language";} 'current_thread';
CURRENT_THREAD_ESC: {"variable.language";} '\\current_thread';
OWNER: {"variable.language";} '\\owner';

GLOBAL: {"storage.modifier";} 'global';
LOCAL: {"storage.modifier";} 'local';
STATIC: {"storage.modifier";} 'static';
FINAL: {"storage.modifier";} 'final';
UNFOLDING_ESC: {"variable.language";} '\\unfolding';
UNFOLDING: {"variable.language";} 'unfolding';
IN_ESC: {"variable.language";} '\\in';
IN: {"variable.language";} 'in';
NEW: {"variable.language";} 'new';
ID: {"variable.language";} 'id';

BOOL: {"keyword.type";} 'boolean';
VOID: {"keyword.type";} 'void';
INT: {"keyword.type";} 'int';
CHAR: {"keyword.type";} 'char';
FLOAT32: {"keyword.type";} 'float32';
FLOAT64: {"keyword.type";} 'float64';

NUMBER : ('0'..'9')+;
DECIMAL_NUMBER : ('0'..'9')+ '.' ('0'..'9')+;
Expand Down Expand Up @@ -143,7 +139,7 @@ HEX_DIGIT
;

mode DEFAULT_MODE;
Identifier : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Identifier : {"entity.name";} ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

COMMENT : '/*' .*? '*/' -> skip;
LINE_COMMENT : '//' .*? ('\n'|EOF) -> skip;
Expand Down
21 changes: 21 additions & 0 deletions src/textMateGenerator/gen/CGL.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gen
import upickle.default.{ReadWriter => RW, macroRW}

/**
* Common Grammar Language
*/
case class CGL(scopeName: String, fileTypes: String, patterns: Seq[MatchPattern]) {
def addPattern(mp: MatchPattern): CGL = {
CGL(scopeName, fileTypes, patterns = patterns :+ mp)
}
}
object CGL{
implicit val rw: RW[CGL] = macroRW
}



case class MatchPattern(name: String, `match`: String)
object MatchPattern {
implicit val rw: RW[MatchPattern] = macroRW
}
48 changes: 47 additions & 1 deletion src/textMateGenerator/gen/Main.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
package gen

class Main {
import hre.io.{RWFile, Readable}
import upickle.default.{macroRW, ReadWriter => RW}
import upickle._
import java.io.File
import org.antlr.v4.runtime
import org.antlr.v4.runtime.{CharStreams, CommonTokenStream}
import vct.antlr4.generated.ANTLRv4Parser.Rules0Context
import vct.antlr4.generated.ANTLRv4ParserPatterns.{GrammarSpec0, RuleSpec0, Rules0}
import vct.antlr4.generated.{ANTLRv4Lexer, ANTLRv4Parser}

import java.io.FileNotFoundException

case object Main {

def parse() = {
val readable: Readable = RWFile(new File("C:\\Development\\Vercors-Dev\\vercors\\src\\parsers\\antlr4\\LangPVLLexer.g4"))
try {
readable.read { reader =>
val stream: runtime.CharStream = CharStreams.fromReader(reader, readable.fileName)
val lexer = new ANTLRv4Lexer(stream)
val tokens = new CommonTokenStream(lexer)
val parser = new ANTLRv4Parser(tokens)
parser.grammarSpec()
}
} catch {
case f: FileNotFoundException => throw f
}
}

def main(args: Array[String]): Unit = {
var textMateGrammar = CGL(args(0), args(1), Nil)
val tree = parse()
tree match {
case GrammarSpec0(grammarDecl, prequelConstructs, rules, modeSpec, _) =>
rules match {
case Rules0(specRules) =>
for (ruleText <- specRules.map(rule => rule.getText))
if (ruleText.matches(".*\\{.*\\}.*"))
textMateGrammar = textMateGrammar.addPattern(
MatchPattern(ruleText.substring(ruleText.indexOf('{') + 2, ruleText.indexOf("}") - 2),
ruleText.split('\'')(1))
)
}
}
print(upickle.default.write(textMateGrammar, indent = 2))
}

}

0 comments on commit 5626e6e

Please sign in to comment.