@@ -43,114 +43,46 @@ func parseUnary(pr *parser) *astNode {
43
43
44
44
}
45
45
46
+ // exponent -> unary ( ("**") unary )*
46
47
func parseExponent (pr * parser ) * astNode {
47
- log .Print ("inside exponent" )
48
-
49
- leftUnary := parseUnary (pr ) // consume first unary
50
- var parent = leftUnary
51
-
52
- for token := pr .peek (); token .tokenType == RaisePower ; token = pr .peek () {
53
-
54
- if pr .eof () {
55
- break // we are just breaking the rule as we in the recusrive expansion of (**) unary
56
- }
57
- pr .next () // consume **
58
- // not checkig for eof as we have checked while calling peek()
59
- rightUnary := parseExponent (pr )
60
-
61
- parent = newASTNode (token , parent , rightUnary , evalInfix ) // exponent is right associated operation for us
62
- }
63
- return parent
48
+ return parseCombinator (pr , evalInfix , parseUnary , RaisePower )
64
49
}
65
50
66
51
// factor -> exponent ( ( "/" | "*" | "%" ) exponent)*
67
52
func parseFactor (pr * parser ) * astNode {
68
- log .Print ("inside factor" )
69
-
70
- leftExponent := parseExponent (pr ) // consume first unary
71
- var parent = leftExponent
72
-
73
- for token := pr .peek (); token .tokenType == Mod || token .tokenType == Asterisk || token .tokenType == Slash ; token = pr .peek () {
74
-
75
- if pr .eof () {
76
- break // we are just breaking the rule as we in the recusrive expansion of (*|/) unary
77
- }
78
- pr .next () // consume * or /
79
- // not checkig for eof as we have checked while calling peek()
80
- rightExponent := parseFactor (pr ) // Makr
81
-
82
- parent = newASTNode (token , parent , rightExponent , evalInfix )
83
- }
84
- return parent
53
+ return parseCombinator (pr , evalInfix , parseExponent , Mod , Asterisk , Slash )
85
54
}
86
55
87
56
// term -> factor (( "+" | "-" ) factor)*
88
57
func parseTerm (pr * parser ) * astNode {
89
- log .Print ("inside term" )
90
- leftUnary := parseFactor (pr ) // consume first unary
91
- var parent = leftUnary
92
- log .Print ("Peek Token : " , pr .peek ())
93
- for token := pr .peek (); token .tokenType == Plus || token .tokenType == Minus ; token = pr .peek () {
94
- log .Print ("Inside Loop" )
95
- if pr .eof () {
96
- break // we are just breaking the rule as we in the recusrive expansion of (+|-) factor
97
- }
98
-
99
- pr .next () // consume + or -
100
- rightUnary := parseTerm (pr )
101
-
102
- parent = newASTNode (token , parent , rightUnary , evalInfix )
103
-
104
- }
105
- log .Print ("Out of Loop" )
106
- return parent
107
-
58
+ return parseCombinator (pr , evalInfix , parseFactor , Plus , Minus )
108
59
}
109
60
110
61
// comparison -> term (( ">" | ">=" | "<" | "<=" ) term)*
111
62
func parseComp (pr * parser ) * astNode {
112
- log .Print ("inside comp" )
113
- leftUnary := parseTerm (pr ) // consume first unary
114
- var parent = leftUnary
115
- for {
116
- token := pr .peek ()
117
- if pr .eof () {
118
- break // we are just breaking the rule as we in the recusrive expansion of (>|>=|<|<=) term
119
- }
120
-
121
- switch token .tokenType {
122
- case LT , GT , LTEQ , GTEQ :
123
- pr .next () // consume > or >= or < or <=
124
- rightUnary := parseComp (pr )
125
-
126
- parent = newASTNode (token , parent , rightUnary , evalInfix )
127
- default :
128
-
129
- return parent
130
- }
131
-
132
- }
133
- return parent
63
+ return parseCombinator (pr , evalInfix , parseTerm , LT , GT , LTEQ , GTEQ )
134
64
}
135
65
136
66
// expr -> comparison ( ( "==" | "!=" ) comparison )*
137
67
func parseExpr (pr * parser ) * astNode {
138
- log .Print ("inside expr" )
139
-
140
- leftUnary := parseComp (pr ) // consume first unary
141
- var parent = leftUnary
68
+ return parseCombinator (pr , evalInfix , parseComp , Eq , NotEq )
69
+ }
142
70
143
- for token := pr .peek (); token .tokenType == Eq || token .tokenType == NotEq ; token = pr .peek () {
144
- if pr .eof () {
145
- break // we are just breaking the rule as we in the recusrive expansion of (== or !=) comparison
71
+ func parseCombinator (pr * parser , evalr evaluator , nonterminalParser parserFn , matchableTokens ... TokenType ) * astNode {
72
+ var tokenMap = make (map [TokenType ]struct {}, len (matchableTokens ))
73
+ for _ , token := range matchableTokens {
74
+ tokenMap [token ] = struct {}{}
75
+ }
76
+ var fn parserFn
77
+ fn = func (pr * parser ) * astNode {
78
+ parent := nonterminalParser (pr ) // parsing first part of the grammar e.g. in grammar E -> F ( operator E )* parses F
79
+ token := pr .peek ()
80
+ _ , ok := tokenMap [token .tokenType ]
81
+ if ! pr .eof () && ok {
82
+ pr .next () // consume token
83
+ return newASTNode (token , parent , fn (pr ), evalr )
146
84
}
147
-
148
- pr .next () // consume == or !=
149
- rightUnary := parseExpr (pr )
150
-
151
- parent = newASTNode (token , parent , rightUnary , evalInfix )
152
-
85
+ return parent
153
86
}
154
- return parent
155
-
87
+ return fn (pr )
156
88
}
0 commit comments