1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- /*
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at https://mozilla.org/MPL/2.0/.
- */
- package parser
- import (
- "errors"
- "fmt"
- )
- func NewUnrecognized(msg string, val rune) error {
- return &UnrecognizedInputError{msg: msg, val: val}
- }
- type UnrecognizedInputError struct {
- msg string
- val rune
- }
- func (e *UnrecognizedInputError) Error() string {
- return fmt.Sprintf("%s: unrecognized input: '%s'", e.msg, string(e.val))
- }
- func (e *UnrecognizedInputError) Unwrap() error {
- return e
- }
- type SM struct {
- stack []*CSTNode
- line, col int
- }
- func (m *SM) Top() *CSTNode {
- return m.stack[len(m.stack)-1]
- }
- func (m *SM) Push(t ASTNode) ASTNode {
- m.stack = append(m.stack, &CSTNode{ASTNode: t})
- return t
- }
- func (m *SM) shift(e rune) (err error) {
- m.col++
- for {
- err = m.Top().ASTNode.Shift(m, e)
- if !errors.Is(err, &UnrecognizedInputError{}) {
- break
- }
- if !m.reduce() {
- break
- }
- }
- return err
- }
- func (m *SM) reduce() bool {
- if len(m.stack) < 2 {
- return false
- }
- last := len(m.stack) - 1
- nodes := m.stack[last-1].Nodes
- nodes = append(nodes, m.stack[last])
- m.stack[last-1].Nodes = nodes
- m.stack = m.stack[:last]
- return true
- }
|