• Jump To … +
    ast.litkal command.litkal generator.litkal grammar.litkal interactive.litkal kal.litkal lexer.litkal literate.litkal parser.litkal sugar.litkal
  • parser.litkal

  • ¶

    The Kal Parser

  • ¶

    The parser takes an array of tokens generated by the lexer and creates an abstract syntax tree (AST) of sytax nodes such as Expressions, If Statements, and Assignment Statements. The actual grammar definition is defined in the grammar module.

    grammar = require './grammar'
  • ¶

    The grammar defines a root object (a Kal File if you inspect the grammar module) that we use to kick off parsing and create a tree.

    GrammarRoot = grammar.GrammarRoot
    Grammar = grammar.Grammar
    
    exports.Grammar = Grammar
  • ¶

    The parse function is the entry point for the compiler. It creates a token stream and parses it, returning the tree.

    function parse(tokens, comments, options)
      ts = new TokenStream(tokens, comments, options)
      AST = new GrammarRoot(ts)
      return AST
    
    exports.parse = parse
  • ¶

    The TokenStream class allows easy navigation through the array of tokens, keeping track of line numbers and comments.

    class TokenStream
      method initialize(tokens, comments, options)
        me.tokens = tokens
        me.comments = comments
        me.options = options
        me.goto_token 0
  • ¶

    Go to the next token and return it.

      method next()
        return me.goto_token me.index+1
  • ¶

    Go back one token and return it.

      method prev()
        return me.goto_token me.index-1
  • ¶

    Return the next token but stay at the current location in the stream.

      method peek(delta_index)
        me.goto_token me.index + delta_index
        token = me.current
        me.goto_token me.index - delta_index
        return token
  • ¶

    Go to a specific token. Generally this is not called directly; it is used by next, prev, and peek.

      method goto_token(index)
        me.index = index
  • ¶

    Return an EOF token if we ran out of tokens.

        if me.index > me.tokens.length - 1
          me.current = {type: 'EOF', text: '', line: 0, value: ''}
        else if me.index < 0
  • ¶

    Actually error out if we try to read before the beginning of the file. This aborts compilation with a compiler error.

          throw 'Parser Error: tried to read before beginning of file'
        else
          me.current = me.tokens[me.index]
  • ¶

    Utility properties for the parser nodes.

        me.type = me.current.type
        me.text = me.current.text
        me.value = me.current.value
        me.line = me.current.line
        return me.current