| 126 | } |
| 127 | |
| 128 | func (l *lexer) Lex(lval *yySymType) int { |
| 129 | // if we are currently parsing an attribute and the next rune suggests that |
| 130 | // this attribute will end, then return a special token indicating that the attribute is |
| 131 | // done parsing |
| 132 | if l.parsingAttribute && !isAttributeRune(l.Peek()) { |
| 133 | l.parsingAttribute = false |
| 134 | return END_ATTRIBUTE |
| 135 | } |
| 136 | |
| 137 | if l.parsingAttribute { |
| 138 | // parse out any scopes here |
| 139 | scopeToken, ok := tryScopeAttribute(&l.Scanner, l.currentScope) |
| 140 | if ok { |
| 141 | l.currentScope = scopeToken |
| 142 | return scopeToken |
| 143 | } |
| 144 | |
| 145 | var err error |
| 146 | lval.staticStr, err = parseAttribute(&l.Scanner) |
| 147 | if err != nil { |
| 148 | l.Error(err.Error()) |
| 149 | return 0 |
| 150 | } |
| 151 | return IDENTIFIER |
| 152 | } |
| 153 | |
| 154 | r := l.Scan() |
| 155 | // now that we know we're not parsing an attribute, let's look for everything else |
| 156 | switch r { |
| 157 | case scanner.EOF: |
| 158 | return 0 |
| 159 | |
| 160 | case scanner.String, scanner.RawString: |
| 161 | var err error |
| 162 | lval.staticStr, err = strconv.Unquote(l.TokenText()) |
| 163 | if err != nil { |
| 164 | l.Error(err.Error()) |
| 165 | return 0 |
| 166 | } |
| 167 | return STRING |
| 168 | |
| 169 | case scanner.Int: |
| 170 | numberText := l.TokenText() |
| 171 | |
| 172 | // first try to parse as duration |
| 173 | duration, ok := tryScanDuration(numberText, &l.Scanner) |
| 174 | if ok { |
| 175 | lval.staticDuration = duration |
| 176 | return DURATION |
| 177 | } |
| 178 | |
| 179 | // if we can't then just try an int |
| 180 | var err error |
| 181 | lval.staticInt, err = strconv.Atoi(numberText) |
| 182 | if err != nil { |
| 183 | l.Error(err.Error()) |
| 184 | return 0 |
| 185 | } |