Module: Kumi::Parser::Grammar

Defined in:
lib/kumi/parser/grammar.rb

Overview

Static grammar tables shared by the lexer and parser. These replace the old per-token TOKEN_METADATA bag: lookups are keyed by a word or token kind, so the data lives once here instead of being copied onto every token instance.

Constant Summary collapse

KEYWORDS =

Bare words that are keywords rather than identifiers. ‘true`/`false` are not here: they are boolean literals, handled directly by the lexer.

{
  'schema' => :schema,
  'input' => :input,
  'value' => :value,
  'let' => :let,
  'trait' => :trait,
  'import' => :import,
  'codegen' => :codegen,
  'do' => :do,
  'end' => :end,
  'on' => :on,
  'base' => :base,
  'fn' => :fn
}.freeze
BOOLEANS =

The two boolean literal words, mapped to their Ruby values.

{ 'true' => true, 'false' => false }.freeze
TYPE_KEYWORDS =

Type keywords introduce input declarations. The value is the canonical type symbol stored on InputDeclaration.

{
  'integer' => :integer,
  'float' => :float,
  'decimal' => :decimal,
  'string' => :string,
  'boolean' => :boolean,
  'any' => :any,
  'array' => :array,
  'hash' => :hash
}.freeze
CONTAINER_TYPES =

Container types whose declarations may open a nested ‘do … end` block.

%i[array hash].freeze
FUNCTION_SUGAR =

Bare-call sugar: ‘name(args)` parses as `fn(:resolved_name, args)`. The value is the function symbol the call lowers to.

{
  'select' => :select,
  'shift' => :shift,
  'roll' => :roll,
  'cross' => :cross,
  'outer' => :outer,
  'index' => :index,
  'to_decimal' => :to_decimal,
  'to_integer' => :to_integer,
  'to_float' => :to_float,
  'to_string' => :to_string
}.freeze
BINARY_OPERATORS =

Binary operators: kind => [precedence, :left/:right, fn_name]. Higher precedence binds tighter. fn_name is the symbol the operator lowers to in the AST (CallExpression fn_name).

{
  power: [7, :right, :power],
  multiply: [6, :left, :multiply],
  divide: [6, :left,  :divide],
  modulo: [6, :left,  :modulo],
  add: [5, :left, :add],
  subtract: [5, :left, :subtract],
  gte: [4, :left,  :>=],
  lte: [4, :left,  :<=],
  gt: [4, :left,  :>],
  lt: [4, :left,  :<],
  eq: [4, :left,  :==],
  ne: [4, :left,  :!=],
  and: [3, :left, :and],
  or: [2, :left, :or]
}.freeze

Class Method Summary collapse

Class Method Details

.binary_operator?(kind) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/kumi/parser/grammar.rb', line 103

def binary_operator?(kind)
  BINARY_OPERATORS.key?(kind)
end

.boolean(word) ⇒ Object



91
92
93
# File 'lib/kumi/parser/grammar.rb', line 91

def boolean(word)
  BOOLEANS[word]
end

.boolean?(word) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/kumi/parser/grammar.rb', line 87

def boolean?(word)
  BOOLEANS.key?(word)
end

.function_sugar(word) ⇒ Object



99
100
101
# File 'lib/kumi/parser/grammar.rb', line 99

def function_sugar(word)
  FUNCTION_SUGAR[word]
end

.keyword(word) ⇒ Object



83
84
85
# File 'lib/kumi/parser/grammar.rb', line 83

def keyword(word)
  KEYWORDS[word]
end

.operator_fn(kind) ⇒ Object



115
116
117
# File 'lib/kumi/parser/grammar.rb', line 115

def operator_fn(kind)
  BINARY_OPERATORS.fetch(kind)[2]
end

.precedence(kind) ⇒ Object



107
108
109
# File 'lib/kumi/parser/grammar.rb', line 107

def precedence(kind)
  BINARY_OPERATORS.fetch(kind)[0]
end

.right_associative?(kind) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/kumi/parser/grammar.rb', line 111

def right_associative?(kind)
  BINARY_OPERATORS.fetch(kind)[1] == :right
end

.type_keyword(word) ⇒ Object



95
96
97
# File 'lib/kumi/parser/grammar.rb', line 95

def type_keyword(word)
  TYPE_KEYWORDS[word]
end