Skip to content

Commit

Permalink
add support for rust with the go runtime (#4207)
Browse files Browse the repository at this point in the history
Tested on rust/examples/*.rs and works for all the examples except
`intellijrust_test_allinone.rs` which takes forever to analyze.
  • Loading branch information
jcrussell authored Aug 19, 2024
1 parent b4cd348 commit 2a3a6bd
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
81 changes: 81 additions & 0 deletions rust/Go/rust_lexer_base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package parser

import (
"github.com/antlr4-go/antlr/v4"
)

type RustLexerBase struct {
*antlr.BaseLexer

lastToken antlr.Token
lastToken2 antlr.Token
}

func (l *RustLexerBase) NextToken() antlr.Token {
next := l.BaseLexer.NextToken()

if next.GetChannel() == antlr.LexerDefaultTokenChannel {
// keep track of the last token on the default channel
l.lastToken2 = l.lastToken
l.lastToken = next
}

return next
}

func (l *RustLexerBase) SOF() bool {
return l.GetInputStream().LA(-1) <= 0
}

func (l *RustLexerBase) floatDotPossible() bool {
next := rune(l.GetInputStream().LA(1))
if next == '.' || next == '_' {
return false
}
if next == 'f' {
// 1.f32
if rune(l.GetInputStream().LA(2)) == '3' && rune(l.GetInputStream().LA(3)) == '2' {
return true
}
//1.f64
if rune(l.GetInputStream().LA(2)) == '6' && rune(l.GetInputStream().LA(3)) == '4' {
return true
}
return false
}
if next >= 'a' && next <= 'z' {
return false
}
if next >= 'A' && next <= 'Z' {
return false
}

return false
}

func (l *RustLexerBase) floatLiteralPossible() bool {
if l.lastToken == nil || l.lastToken2 == nil {
return true
}
if l.lastToken.GetTokenType() != RustLexerDOT {
return true
}

switch l.lastToken2.GetTokenType() {
case RustLexerCHAR_LITERAL, RustLexerSTRING_LITERAL,
RustLexerRAW_STRING_LITERAL, RustLexerBYTE_LITERAL,
RustLexerBYTE_STRING_LITERAL, RustLexerRAW_BYTE_STRING_LITERAL,
RustLexerINTEGER_LITERAL, RustLexerDEC_LITERAL, RustLexerHEX_LITERAL,
RustLexerOCT_LITERAL, RustLexerBIN_LITERAL, RustLexerKW_SUPER,
RustLexerKW_SELFVALUE, RustLexerKW_SELFTYPE, RustLexerKW_CRATE,
RustLexerKW_DOLLARCRATE, RustLexerGT, RustLexerRCURLYBRACE,
RustLexerRSQUAREBRACKET, RustLexerRPAREN, RustLexerKW_AWAIT,
RustLexerNON_KEYWORD_IDENTIFIER, RustLexerRAW_IDENTIFIER,
RustLexerKW_MACRORULES:
return false
default:
return true
}

return false
}
14 changes: 14 additions & 0 deletions rust/Go/rust_parser_base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package parser

import (
"github.com/antlr4-go/antlr/v4"
)

// RustParserBase implementation.
type RustParserBase struct {
*antlr.BaseParser
}

func (p *RustParserBase) next(expect int) bool {
return p.GetInputStream().LA(1) == expect
}
56 changes: 56 additions & 0 deletions rust/Go/transformGrammar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import sys, os, re, shutil
from glob import glob
from pathlib import Path

def main(argv):
for file in glob("./*Lexer.g4"):
fix_lexer(file)
for file in glob("./*Parser.g4"):
fix_parser(file)

def fix_lexer(file_path):
print("Altering " + file_path)
if not os.path.exists(file_path):
print(f"Could not find file: {file_path}")
sys.exit(1)
parts = os.path.split(file_path)
file_name = parts[-1]

shutil.move(file_path, file_path + ".bak")
input_file = open(file_path + ".bak",'r')
output_file = open(file_path, 'w')
for x in input_file:
if 'this.' in x and '}?' in x:
x = x.replace('this.', 'p.')
elif 'this.' in x:
x = x.replace('this.', 'l.')
output_file.write(x)
output_file.flush()

print("Writing ...")
input_file.close()
output_file.close()

def fix_parser(file_path):
print("Altering " + file_path)
if not os.path.exists(file_path):
print(f"Could not find file: {file_path}")
sys.exit(1)
parts = os.path.split(file_path)
file_name = parts[-1]

shutil.move(file_path, file_path + ".bak")
input_file = open(file_path + ".bak",'r')
output_file = open(file_path, 'w')
for x in input_file:
if 'this.' in x:
x = x.replace('this.', 'p.')
output_file.write(x)
output_file.flush()

print("Writing ...")
input_file.close()
output_file.close()

if __name__ == '__main__':
main(sys.argv)

0 comments on commit 2a3a6bd

Please sign in to comment.