Skip to content

Commit

Permalink
Support templated method calls in Typescript by allowing recursive lo…
Browse files Browse the repository at this point in the history
…okaheads.
  • Loading branch information
inspirer committed Sep 3, 2017
1 parent 8a61a13 commit 265a170
Show file tree
Hide file tree
Showing 10 changed files with 20,413 additions and 20,206 deletions.
11 changes: 5 additions & 6 deletions tm-go/parsers/json/parser.go
Expand Up @@ -206,17 +206,16 @@ restart:
return int32(tok)
}

func (p *Parser) AtEmptyObject() bool {
return p.lookahead(0, 42)
func AtEmptyObject(lexer *Lexer, next int32) bool {
return lookahead(lexer, next, 0, 42)
}

func (p *Parser) lookahead(start, end int8) bool {
var lexer Lexer = *p.lexer
func lookahead(l *Lexer, next int32, start, end int8) bool {
var lexer Lexer = *l

var allocated [64]stackEntry
state := start
stack := append(allocated[:0], stackEntry{state: state})
next := p.next.symbol

for state != end {
action := tmAction[state]
Expand Down Expand Up @@ -266,7 +265,7 @@ func (p *Parser) lookahead(start, end int8) bool {
func (p *Parser) applyRule(rule int32, lhs *stackEntry, rhs []stackEntry) {
switch rule {
case 32:
if p.AtEmptyObject() {
if AtEmptyObject(p.lexer, p.next.symbol) {
lhs.sym.symbol = 23 /* lookahead_EmptyObject */
} else {
lhs.sym.symbol = 25 /* lookahead_notEmptyObject */
Expand Down
7 changes: 7 additions & 0 deletions tm-parsers/js/ast/ast.go
Expand Up @@ -695,6 +695,13 @@ type Arguments struct {
Node
}

func (n Arguments) TypeArguments() *TypeArguments {
if child := n.Child(selector.TypeArguments); child != nil {
return &TypeArguments{child}
}
return nil
}

func (n Arguments) List() []Expression {
nodes := n.Children(selector.Expression)
var result []Expression = make([]Expression, 0, len(nodes))
Expand Down
15 changes: 10 additions & 5 deletions tm-parsers/js/js.tm
Expand Up @@ -7,8 +7,9 @@ lang = "js"
package = "github.com/inspirer/textmapper/tm-parsers/js"
eventBased = true
eventFields = true
recursiveLookaheads = true
reportTokens = [MultiLineComment, SingleLineComment, invalid_token,
NoSubstitutionTemplate, TemplateHead, TemplateMiddle, TemplateTail]
NoSubstitutionTemplate, TemplateHead, TemplateMiddle, TemplateTail]
extraTypes = ["InsertedSemicolon"]

:: lexer
Expand Down Expand Up @@ -548,7 +549,7 @@ NewTarget -> NewTarget :
'new' '.' 'target' ;

NewExpression<Yield, Await, NoAsync> -> Expression /* interface */:
MemberExpression
MemberExpression (?= !StartOfParametrizedCall)
| [!StartWithLet] 'new' expr=NewExpression<~NoAsync> -> NewExpression
;

Expand All @@ -569,8 +570,12 @@ SuperCall<Yield, Await> :
;

Arguments<Yield, Await> -> Arguments :
# TODO TypeArgumentsopt
'(' (list=ArgumentList ','?)? ')' ;
(?= StartOfParametrizedCall) TypeArguments '(' (list=ArgumentList ','?)? ')'
| '(' (list=ArgumentList ','?)? ')'
;

StartOfParametrizedCall:
TypeArguments '(' ;

ArgumentList<Yield, Await> :
AssignmentExpression<+In>
Expand All @@ -581,7 +586,7 @@ ArgumentList<Yield, Await> :

LeftHandSideExpression<Yield, Await, NoAsync> -> Expression /* interface */:
NewExpression
| CallExpression
| CallExpression (?= !StartOfParametrizedCall)
;

UpdateExpression<Yield, Await> -> Expression /* interface */:
Expand Down
93 changes: 54 additions & 39 deletions tm-parsers/js/listener.go

Large diffs are not rendered by default.

75 changes: 56 additions & 19 deletions tm-parsers/js/parser.go
Expand Up @@ -21,7 +21,7 @@ func (e SyntaxError) Error() string {
}

func (p *Parser) Parse(lexer *Lexer) error {
return p.parse(2, 5191, lexer)
return p.parse(3, 5252, lexer)
}

func lookaheadNext(lexer *Lexer) int32 {
Expand All @@ -34,24 +34,53 @@ restart:
return int32(tok)
}

func (p *Parser) AtStartOfFunctionType() bool {
return p.lookahead(0, 5188)
func lookaheadRule(lexer *Lexer, next, rule int32, lhs *stackEntry) {
switch rule {
case 3503:
if lookahead(lexer, next, 0, 5248) {
lhs.sym.symbol = 347 /* lookahead_StartOfParametrizedCall */
} else {
lhs.sym.symbol = 287 /* lookahead_notStartOfParametrizedCall */
}
return
case 3504:
if lookahead(lexer, next, 2, 5250) {
lhs.sym.symbol = 855 /* lookahead_StartOfMappedType */
} else {
lhs.sym.symbol = 847 /* lookahead_notStartOfMappedType */
}
return
case 3505:
if lookahead(lexer, next, 1, 5249) {
lhs.sym.symbol = 861 /* lookahead_StartOfFunctionType */
} else {
lhs.sym.symbol = 840 /* lookahead_notStartOfFunctionType */
}
return
}
}

func (p *Parser) AtStartOfMappedType() bool {
return p.lookahead(1, 5189)
func AtStartOfParametrizedCall(lexer *Lexer, next int32) bool {
return lookahead(lexer, next, 0, 5248)
}

func (p *Parser) lookahead(start, end int16) bool {
var lexer Lexer = *p.lexer
func AtStartOfFunctionType(lexer *Lexer, next int32) bool {
return lookahead(lexer, next, 1, 5249)
}

func AtStartOfMappedType(lexer *Lexer, next int32) bool {
return lookahead(lexer, next, 2, 5250)
}

func lookahead(l *Lexer, next int32, start, end int16) bool {
var lexer Lexer = *l
var alloc2, alloc3 [8]int
lexer.Stack = alloc2[:0]
lexer.Opened = alloc3[:0]

var allocated [64]stackEntry
state := start
stack := append(allocated[:0], stackEntry{state: state})
next := p.next.symbol

for state != end {
action := tmAction[state]
Expand All @@ -71,6 +100,7 @@ func (p *Parser) lookahead(start, end int16) bool {
var entry stackEntry
entry.sym.symbol = tmRuleSymbol[rule]
stack = stack[:len(stack)-ln]
lookaheadRule(&lexer, next, rule, &entry)
state = gotoState(stack[len(stack)-1].state, entry.sym.symbol)
entry.state = state
stack = append(stack, entry)
Expand Down Expand Up @@ -136,24 +166,31 @@ func gotoState(state int16, symbol int32) int16 {

func (p *Parser) applyRule(rule int32, lhs *stackEntry, rhs []stackEntry) {
switch rule {
case 2644: // IterationStatement : 'for' '(' 'async' 'of' AssignmentExpression_In ')' Statement
case 2659: // IterationStatement : 'for' '(' 'async' 'of' AssignmentExpression_In ')' Statement
p.listener(IdentifierReference, rhs[2].sym.offset, rhs[2].sym.endoffset)
case 2658: // IterationStatement_Await : 'for' '(' 'async' 'of' AssignmentExpression_Await_In ')' Statement_Await
case 2673: // IterationStatement_Await : 'for' '(' 'async' 'of' AssignmentExpression_Await_In ')' Statement_Await
p.listener(IdentifierReference, rhs[2].sym.offset, rhs[2].sym.endoffset)
case 2672: // IterationStatement_Yield : 'for' '(' 'async' 'of' AssignmentExpression_In_Yield ')' Statement_Yield
case 2687: // IterationStatement_Yield : 'for' '(' 'async' 'of' AssignmentExpression_In_Yield ')' Statement_Yield
p.listener(IdentifierReference, rhs[2].sym.offset, rhs[2].sym.endoffset)
case 3488:
if p.AtStartOfMappedType() {
lhs.sym.symbol = 852 /* lookahead_StartOfMappedType */
case 3503:
if AtStartOfParametrizedCall(p.lexer, p.next.symbol) {
lhs.sym.symbol = 347 /* lookahead_StartOfParametrizedCall */
} else {
lhs.sym.symbol = 287 /* lookahead_notStartOfParametrizedCall */
}
return
case 3504:
if AtStartOfMappedType(p.lexer, p.next.symbol) {
lhs.sym.symbol = 855 /* lookahead_StartOfMappedType */
} else {
lhs.sym.symbol = 844 /* lookahead_notStartOfMappedType */
lhs.sym.symbol = 847 /* lookahead_notStartOfMappedType */
}
return
case 3489:
if p.AtStartOfFunctionType() {
lhs.sym.symbol = 858 /* lookahead_StartOfFunctionType */
case 3505:
if AtStartOfFunctionType(p.lexer, p.next.symbol) {
lhs.sym.symbol = 861 /* lookahead_StartOfFunctionType */
} else {
lhs.sym.symbol = 837 /* lookahead_notStartOfFunctionType */
lhs.sym.symbol = 840 /* lookahead_notStartOfFunctionType */
}
return
}
Expand Down
3 changes: 3 additions & 0 deletions tm-parsers/js/parser_impl.go
Expand Up @@ -85,6 +85,9 @@ func (p *Parser) parse(start, end int16, lexer *Lexer) error {
entry.sym.symbol = tmRuleSymbol[rule]
rhs := p.stack[len(p.stack)-ln:]
p.stack = p.stack[:len(p.stack)-ln]
for ln > 0 && rhs[ln-1].sym.offset == rhs[ln-1].sym.endoffset {
ln--
}
if ln == 0 {
entry.sym.offset, _ = lexer.Pos()
entry.sym.endoffset = entry.sym.offset
Expand Down

0 comments on commit 265a170

Please sign in to comment.