Create a new Xcode playground for Swift.
This takes the example from https://github.com/janyou/Antlr-Swift-Runtime/tree/master/Test and packages it into an Xcode playground. This allows the user to interact with the grammar directly inside Xcode, and serves as a live demo of the Swift support. Update the docs to match.
This commit is contained in:
parent
aff8cba61a
commit
b0c3824357
|
@ -21,93 +21,27 @@ You will find Swift runtime (framework project) in
|
|||
antlr4/runtime/Swift
|
||||
```
|
||||
|
||||
#### 4. Example
|
||||
#### 4. Example playground
|
||||
|
||||
The example from [here](https://github.com/janyou/Antlr-Swift-Runtime/tree/master/Test)
|
||||
The Swift runtime includes an Xcode playground to get started with.
|
||||
|
||||
(1). Hello.g4
|
||||
In Xcode, open `antlr4/runtime/Swift/Antlr4.xcworkspace`. Select
|
||||
"Antlr4 OSX > My Mac" as the build target, and build the project as normal.
|
||||
The playground should then be active.
|
||||
|
||||
The playground includes a simple grammar called "Hello", and an example for
|
||||
walking the parse tree. You should see in the playground output that it is
|
||||
printing messages for each node in the parse tree as it walks.
|
||||
|
||||
The playground shows how to create a lexer, token stream, and parser, and
|
||||
how to execute the parse.
|
||||
|
||||
The grammar is defined in the playground's `Resources/Hello.g4`. The parser
|
||||
was generated from the grammar using Antlr4 like this:
|
||||
|
||||
```
|
||||
grammar Hello;
|
||||
r : 'hello' ID ;
|
||||
ID : [a-z]+ ;
|
||||
WS : [ \t\r\n]+ -> skip ;
|
||||
```
|
||||
|
||||
(2). generate lexer/parser/visitor from Hello.g4 file
|
||||
|
||||
```
|
||||
$ antlr4 -Dlanguage=Swift -visitor -o gen Hello.g4
|
||||
```
|
||||
|
||||
in gen folder:
|
||||
|
||||
```
|
||||
Hello.tokens
|
||||
HelloBaseListener.swift
|
||||
HelloBaseVisitor.swift
|
||||
HelloLexer.swift
|
||||
HelloLexer.tokens
|
||||
HelloLexerATN.swift
|
||||
HelloListener.swift
|
||||
HelloParser.swift
|
||||
HelloParserATN.swift
|
||||
HelloVisitor.swift
|
||||
```
|
||||
|
||||
(3). make a custom listener
|
||||
|
||||
```
|
||||
public class HelloWalker: HelloBaseListener{
|
||||
public override func enterR(_ ctx: HelloParser.RContext) {
|
||||
print( "enterR: " + ((ctx.ID()?.getText()) ?? ""))
|
||||
}
|
||||
|
||||
public override func exitR(_ ctx: HelloParser.RContext) {
|
||||
print( "exitR ")
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
(4). call and run
|
||||
|
||||
|
||||
|
||||
add TestHello.txt
|
||||
|
||||
```
|
||||
hello world
|
||||
```
|
||||
|
||||
run:
|
||||
|
||||
```
|
||||
import Antlr4
|
||||
|
||||
....
|
||||
|
||||
do {
|
||||
|
||||
let textFileName = "TestHello.txt"
|
||||
if let textFilePath = Bundle.main.path(forResource: textFileName, ofType: nil) {
|
||||
let lexer = HelloLexer(ANTLRFileStream(textFilePath))
|
||||
let tokens = CommonTokenStream(lexer)
|
||||
let parser = try HelloParser(tokens)
|
||||
let tree = try parser.r()
|
||||
let walker = ParseTreeWalker()
|
||||
try walker.walk(HelloWalker(),tree)
|
||||
} else {
|
||||
print("error occur: can not open \(textFileName)")
|
||||
}
|
||||
|
||||
}catch ANTLRException.cannotInvokeStartRule {
|
||||
print("error occur: CannotInvokeStartRule")
|
||||
}catch ANTLRException.recognition(let e ) {
|
||||
print("error occur\(e)")
|
||||
}catch {
|
||||
print("error occur")
|
||||
}
|
||||
cd 'antlr4/runtime/Swift/Antlr4 playground.playground/Resources'
|
||||
antlr4 -Dlanguage=Swift -visitor -o ../Sources/Autogen Hello.g4
|
||||
```
|
||||
|
||||
The example tree walker is in `Sources/HelloWalker.swift`.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import Antlr4
|
||||
|
||||
var input = "hello world"
|
||||
|
||||
let lexer = HelloLexer(ANTLRInputStream(input))
|
||||
let tokens = CommonTokenStream(lexer)
|
||||
|
||||
do {
|
||||
let parser = try HelloParser(tokens)
|
||||
|
||||
let tree = try parser.r()
|
||||
let walker = ParseTreeWalker()
|
||||
try walker.walk(HelloWalker(), tree)
|
||||
}
|
||||
catch ANTLRException.cannotInvokeStartRule {
|
||||
print("Error: cannot invoke start rule.")
|
||||
}
|
||||
catch ANTLRException.recognition(let e) {
|
||||
print("Unrecoverable recognition error: \(e)")
|
||||
}
|
||||
catch {
|
||||
print("Unknown error: \(error)")
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
// Define a grammar called Hello
|
||||
grammar Hello;
|
||||
r : 'hello' ID ; // match keyword hello followed by an identifier
|
||||
ID : [a-z]+ ; // match lower-case identifiers
|
||||
WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
|
|
@ -0,0 +1 @@
|
|||
hello world
|
|
@ -0,0 +1,4 @@
|
|||
T__0=1
|
||||
ID=2
|
||||
WS=3
|
||||
'hello'=1
|
|
@ -0,0 +1,50 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
|
||||
import Antlr4
|
||||
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link HelloListener},
|
||||
* which can be extended to create a listener which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*/
|
||||
open class HelloBaseListener: HelloListener {
|
||||
public init() { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func enterR(_ ctx: HelloParser.RContext) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func exitR(_ ctx: HelloParser.RContext) { }
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func enterEveryRule(_ ctx: ParserRuleContext) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func exitEveryRule(_ ctx: ParserRuleContext) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func visitTerminal(_ node: TerminalNode) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
open func visitErrorNode(_ node: ErrorNode) { }
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
import Antlr4
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link HelloVisitor},
|
||||
* which can be extended to create a visitor which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
open class HelloBaseVisitor<T>: AbstractParseTreeVisitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
open func visitR(_ ctx: HelloParser.RContext) -> T? { return visitChildren(ctx) }
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
import Antlr4
|
||||
|
||||
open class HelloLexer: Lexer {
|
||||
internal static var _decisionToDFA: [DFA] = {
|
||||
var decisionToDFA = [DFA]()
|
||||
let length = HelloLexer._ATN.getNumberOfDecisions()
|
||||
for i in 0..<length {
|
||||
decisionToDFA.append(DFA(HelloLexer._ATN.getDecisionState(i)!, i))
|
||||
}
|
||||
return decisionToDFA
|
||||
}()
|
||||
|
||||
internal static let _sharedContextCache:PredictionContextCache = PredictionContextCache()
|
||||
public static let T__0=1, ID=2, WS=3
|
||||
public static let modeNames: [String] = [
|
||||
"DEFAULT_MODE"
|
||||
]
|
||||
|
||||
public static let ruleNames: [String] = [
|
||||
"T__0", "ID", "WS"
|
||||
]
|
||||
|
||||
private static let _LITERAL_NAMES: [String?] = [
|
||||
nil, "'hello'"
|
||||
]
|
||||
private static let _SYMBOLIC_NAMES: [String?] = [
|
||||
nil, nil, "ID", "WS"
|
||||
]
|
||||
public static let VOCABULARY: Vocabulary = Vocabulary(_LITERAL_NAMES, _SYMBOLIC_NAMES)
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
//@Deprecated
|
||||
public let tokenNames: [String?]? = {
|
||||
let length = _SYMBOLIC_NAMES.count
|
||||
var tokenNames = [String?](repeating: nil, count: length)
|
||||
for i in 0..<length {
|
||||
var name = VOCABULARY.getLiteralName(i)
|
||||
if name == nil {
|
||||
name = VOCABULARY.getSymbolicName(i)
|
||||
}
|
||||
if name == nil {
|
||||
name = "<INVALID>"
|
||||
}
|
||||
tokenNames[i] = name
|
||||
}
|
||||
return tokenNames
|
||||
}()
|
||||
|
||||
override
|
||||
open func getTokenNames() -> [String?]? {
|
||||
return tokenNames
|
||||
}
|
||||
|
||||
open override func getVocabulary() -> Vocabulary {
|
||||
return HelloLexer.VOCABULARY
|
||||
}
|
||||
|
||||
public override init(_ input: CharStream) {
|
||||
RuntimeMetaData.checkVersion("4.6", RuntimeMetaData.VERSION)
|
||||
super.init(input)
|
||||
_interp = LexerATNSimulator(self, HelloLexer._ATN, HelloLexer._decisionToDFA, HelloLexer._sharedContextCache)
|
||||
}
|
||||
|
||||
override
|
||||
open func getGrammarFileName() -> String { return "Hello.g4" }
|
||||
|
||||
override
|
||||
open func getRuleNames() -> [String] { return HelloLexer.ruleNames }
|
||||
|
||||
override
|
||||
open func getSerializedATN() -> String { return HelloLexer._serializedATN }
|
||||
|
||||
override
|
||||
open func getModeNames() -> [String] { return HelloLexer.modeNames }
|
||||
|
||||
override
|
||||
open func getATN() -> ATN { return HelloLexer._ATN }
|
||||
|
||||
public static let _serializedATN: String = HelloLexerATN().jsonString
|
||||
public static let _ATN: ATN = ATNDeserializer().deserializeFromJson(_serializedATN)
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
T__0=1
|
||||
ID=2
|
||||
WS=3
|
||||
'hello'=1
|
|
@ -0,0 +1,3 @@
|
|||
class HelloLexerATN {
|
||||
let jsonString: String = "{\"version\":3,\"uuid\":\"aadb8d7e-aeef-4415-ad2b-8204d6cf042e\",\"grammarType\":0,\"maxTokenType\":3,\"states\":[{\"stateType\":6,\"ruleIndex\":-1},{\"stateType\":2,\"ruleIndex\":0},{\"stateType\":7,\"ruleIndex\":0},{\"stateType\":2,\"ruleIndex\":1},{\"stateType\":7,\"ruleIndex\":1},{\"stateType\":2,\"ruleIndex\":2},{\"stateType\":7,\"ruleIndex\":2},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":1},{\"stateType\":4,\"ruleIndex\":1,\"detailStateNumber\":15},{\"stateType\":8,\"ruleIndex\":1},{\"stateType\":11,\"ruleIndex\":1},{\"stateType\":12,\"ruleIndex\":1,\"detailStateNumber\":16},{\"stateType\":1,\"ruleIndex\":2},{\"stateType\":4,\"ruleIndex\":2,\"detailStateNumber\":20},{\"stateType\":8,\"ruleIndex\":2},{\"stateType\":11,\"ruleIndex\":2},{\"stateType\":12,\"ruleIndex\":2,\"detailStateNumber\":21},{\"stateType\":1,\"ruleIndex\":2},{\"stateType\":1,\"ruleIndex\":2}],\"nonGreedyStates\":[],\"precedenceStates\":[],\"ruleToStartState\":[{\"stateNumber\":1,\"ruleToTokenType\":1},{\"stateNumber\":3,\"ruleToTokenType\":2},{\"stateNumber\":5,\"ruleToTokenType\":3}],\"modeToStartState\":[0],\"nsets\":2,\"IntervalSet\":[{\"size\":1,\"containsEof\":0,\"Intervals\":[{\"a\":97,\"b\":122}]},{\"size\":3,\"containsEof\":0,\"Intervals\":[{\"a\":9,\"b\":10},{\"a\":13,\"b\":13},{\"a\":32,\"b\":32}]}],\"allTransitionsBuilder\":[[{\"src\":0,\"trg\":1,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0},{\"src\":0,\"trg\":3,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0},{\"src\":0,\"trg\":5,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":1,\"trg\":7,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":3,\"trg\":14,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":5,\"trg\":19,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":7,\"trg\":8,\"edgeType\":5,\"arg1\":104,\"arg2\":0,\"arg3\":0}],[{\"src\":8,\"trg\":9,\"edgeType\":5,\"arg1\":101,\"arg2\":0,\"arg3\":0}],[{\"src\":9,\"trg\":10,\"edgeType\":5,\"arg1\":108,\"arg2\":0,\"arg3\":0}],[{\"src\":10,\"trg\":11,\"edgeType\":5,\"arg1\":108,\"arg2\":0,\"arg3\":0}],[{\"src\":11,\"trg\":12,\"edgeType\":5,\"arg1\":111,\"arg2\":0,\"arg3\":0}],[{\"src\":12,\"trg\":2,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":13,\"trg\":15,\"edgeType\":7,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":14,\"trg\":13,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":15,\"trg\":16,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":16,\"trg\":14,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0},{\"src\":16,\"trg\":17,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":17,\"trg\":4,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":18,\"trg\":20,\"edgeType\":7,\"arg1\":1,\"arg2\":0,\"arg3\":0}],[{\"src\":19,\"trg\":18,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":20,\"trg\":21,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":21,\"trg\":19,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0},{\"src\":21,\"trg\":22,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":22,\"trg\":23,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":23,\"trg\":24,\"edgeType\":6,\"arg1\":2,\"arg2\":0,\"arg3\":0}],[{\"src\":24,\"trg\":6,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}]],\"decisionToState\":[0,16,21],\"lexerActions\":[{\"actionType\":6,\"a\":0,\"b\":0}]}"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
import Antlr4
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link HelloParser}.
|
||||
*/
|
||||
public protocol HelloListener: ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link HelloParser#r}.
|
||||
- Parameters:
|
||||
- ctx: the parse tree
|
||||
*/
|
||||
func enterR(_ ctx: HelloParser.RContext)
|
||||
/**
|
||||
* Exit a parse tree produced by {@link HelloParser#r}.
|
||||
- Parameters:
|
||||
- ctx: the parse tree
|
||||
*/
|
||||
func exitR(_ ctx: HelloParser.RContext)
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
import Antlr4
|
||||
|
||||
open class HelloParser: Parser {
|
||||
|
||||
internal static var _decisionToDFA: [DFA] = {
|
||||
var decisionToDFA = [DFA]()
|
||||
let length = HelloParser._ATN.getNumberOfDecisions()
|
||||
for i in 0..<length {
|
||||
decisionToDFA.append(DFA(HelloParser._ATN.getDecisionState(i)!, i))
|
||||
}
|
||||
return decisionToDFA
|
||||
}()
|
||||
internal static let _sharedContextCache: PredictionContextCache = PredictionContextCache()
|
||||
public enum Tokens: Int {
|
||||
case EOF = -1, T__0 = 1, ID = 2, WS = 3
|
||||
}
|
||||
public static let RULE_r = 0
|
||||
public static let ruleNames: [String] = [
|
||||
"r"
|
||||
]
|
||||
|
||||
private static let _LITERAL_NAMES: [String?] = [
|
||||
nil, "'hello'"
|
||||
]
|
||||
private static let _SYMBOLIC_NAMES: [String?] = [
|
||||
nil, nil, "ID", "WS"
|
||||
]
|
||||
public static let VOCABULARY: Vocabulary = Vocabulary(_LITERAL_NAMES, _SYMBOLIC_NAMES)
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
//@Deprecated
|
||||
public let tokenNames: [String?]? = {
|
||||
let length = _SYMBOLIC_NAMES.count
|
||||
var tokenNames = [String?](repeating: nil, count: length)
|
||||
for i in 0..<length {
|
||||
var name = VOCABULARY.getLiteralName(i)
|
||||
if name == nil {
|
||||
name = VOCABULARY.getSymbolicName(i)
|
||||
}
|
||||
if name == nil {
|
||||
name = "<INVALID>"
|
||||
}
|
||||
tokenNames[i] = name
|
||||
}
|
||||
return tokenNames
|
||||
}()
|
||||
|
||||
override
|
||||
open func getTokenNames() -> [String?]? {
|
||||
return tokenNames
|
||||
}
|
||||
|
||||
override
|
||||
open func getGrammarFileName() -> String { return "Hello.g4" }
|
||||
|
||||
override
|
||||
open func getRuleNames() -> [String] { return HelloParser.ruleNames }
|
||||
|
||||
override
|
||||
open func getSerializedATN() -> String { return HelloParser._serializedATN }
|
||||
|
||||
override
|
||||
open func getATN() -> ATN { return HelloParser._ATN }
|
||||
|
||||
open override func getVocabulary() -> Vocabulary {
|
||||
return HelloParser.VOCABULARY
|
||||
}
|
||||
|
||||
public override init(_ input:TokenStream)throws {
|
||||
RuntimeMetaData.checkVersion("4.6", RuntimeMetaData.VERSION)
|
||||
try super.init(input)
|
||||
_interp = ParserATNSimulator(self,HelloParser._ATN,HelloParser._decisionToDFA, HelloParser._sharedContextCache)
|
||||
}
|
||||
open class RContext:ParserRuleContext {
|
||||
open func ID() -> TerminalNode? { return getToken(HelloParser.Tokens.ID.rawValue, 0) }
|
||||
open override func getRuleIndex() -> Int { return HelloParser.RULE_r }
|
||||
override
|
||||
open func enterRule(_ listener: ParseTreeListener) {
|
||||
if listener is HelloListener {
|
||||
(listener as! HelloListener).enterR(self)
|
||||
}
|
||||
}
|
||||
override
|
||||
open func exitRule(_ listener: ParseTreeListener) {
|
||||
if listener is HelloListener {
|
||||
(listener as! HelloListener).exitR(self)
|
||||
}
|
||||
}
|
||||
override
|
||||
open func accept<T>(_ visitor: ParseTreeVisitor<T>) -> T? {
|
||||
if visitor is HelloVisitor {
|
||||
return (visitor as! HelloVisitor<T>).visitR(self)
|
||||
}else if visitor is HelloBaseVisitor {
|
||||
return (visitor as! HelloBaseVisitor<T>).visitR(self)
|
||||
}
|
||||
else {
|
||||
return visitor.visitChildren(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@discardableResult
|
||||
open func r() throws -> RContext {
|
||||
var _localctx: RContext = RContext(_ctx, getState())
|
||||
try enterRule(_localctx, 0, HelloParser.RULE_r)
|
||||
defer {
|
||||
try! exitRule()
|
||||
}
|
||||
do {
|
||||
try enterOuterAlt(_localctx, 1)
|
||||
setState(2)
|
||||
try match(HelloParser.Tokens.T__0.rawValue)
|
||||
setState(3)
|
||||
try match(HelloParser.Tokens.ID.rawValue)
|
||||
|
||||
}
|
||||
catch ANTLRException.recognition(let re) {
|
||||
_localctx.exception = re
|
||||
_errHandler.reportError(self, re)
|
||||
try _errHandler.recover(self, re)
|
||||
}
|
||||
|
||||
return _localctx
|
||||
}
|
||||
|
||||
public static let _serializedATN : String = HelloParserATN().jsonString
|
||||
public static let _ATN: ATN = ATNDeserializer().deserializeFromJson(_serializedATN)
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
class HelloParserATN {
|
||||
let jsonString: String = "{\"version\":3,\"uuid\":\"aadb8d7e-aeef-4415-ad2b-8204d6cf042e\",\"grammarType\":1,\"maxTokenType\":3,\"states\":[{\"stateType\":2,\"ruleIndex\":0},{\"stateType\":7,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0},{\"stateType\":1,\"ruleIndex\":0}],\"nonGreedyStates\":[],\"precedenceStates\":[],\"ruleToStartState\":[{\"stateNumber\":0}],\"modeToStartState\":[],\"nsets\":0,\"IntervalSet\":[],\"allTransitionsBuilder\":[[{\"src\":0,\"trg\":2,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[{\"src\":2,\"trg\":3,\"edgeType\":5,\"arg1\":1,\"arg2\":0,\"arg3\":0}],[{\"src\":3,\"trg\":4,\"edgeType\":5,\"arg1\":2,\"arg2\":0,\"arg3\":0}],[{\"src\":4,\"trg\":1,\"edgeType\":1,\"arg1\":0,\"arg2\":0,\"arg3\":0}],[]],\"decisionToState\":[],\"lexerActions\":[]}"
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Generated from Hello.g4 by ANTLR 4.6
|
||||
import Antlr4
|
||||
|
||||
/**
|
||||
* This interface defines a complete generic visitor for a parse tree produced
|
||||
* by {@link HelloParser}.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
open class HelloVisitor<T>: ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by {@link HelloParser#r}.
|
||||
- Parameters:
|
||||
- ctx: the parse tree
|
||||
- returns: the visitor result
|
||||
*/
|
||||
open func visitR(_ ctx: HelloParser.RContext) -> T{
|
||||
fatalError(#function + " must be overridden")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import Antlr4
|
||||
|
||||
public class HelloWalker: HelloBaseListener {
|
||||
public override func enterR(_ ctx: HelloParser.RContext) {
|
||||
print("enterR: \(ctx.IDText())")
|
||||
}
|
||||
|
||||
public override func exitR(_ ctx: HelloParser.RContext) {
|
||||
print("exitR: \(ctx.IDText())")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fileprivate extension HelloParser.RContext {
|
||||
fileprivate func IDText() -> String {
|
||||
return ID()?.getText() ?? ""
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
7
runtime/Swift/Antlr4 playground.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
runtime/Swift/Antlr4 playground.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "container:Antlr4.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "container:Antlr4 playground.playground">
|
||||
</FileRef>
|
||||
</Workspace>
|
Loading…
Reference in New Issue