Class: Yadriggy::Syntax
- Inherits:
-
Object
- Object
- Yadriggy::Syntax
- Defined in:
- lib/yadriggy/syntax.rb
Overview
Syntax checker.
Instance Attribute Summary collapse
-
#debug ⇒ Object
writeonly
debugging mode is on if true.
-
#hash ⇒ Hash
readonly
The grammar rules.
Class Method Summary collapse
-
.check_syntax(block) ⇒ Boolean
Checks the syntax of the grammar rules.
-
.last_error ⇒ String
The error message for the grammar rule last checked.
-
.ruby_syntax ⇒ Syntax
Defines Ruby syntax and returns its Syntax object.
Instance Method Summary collapse
-
#add_rules(syntax = nil) { ... } ⇒ Object
Adds rules.
-
#check(tree) ⇒ Boolean
Checks the syntax of the given AST.
-
#check_error(astree) ⇒ void
Checks the syntax of the given AST and raise an error if a syntax error is found.
-
#check_usertype(user_type, tree) ⇒ Boolean
Checks whether the given AST matches the grammar rule for the given user type.
-
#error ⇒ String
Returns an error message.
-
#initialize(ast) ⇒ Syntax
constructor
A new instance of Syntax.
-
#raise_error ⇒ Object
Raises a syntax-error exception.
- #update_hash(body) ⇒ void
Constructor Details
#initialize(ast) ⇒ Syntax
Returns a new instance of Syntax.
60 61 62 63 64 65 66 |
# File 'lib/yadriggy/syntax.rb', line 60 def initialize(ast) @error_loc = nil @error_msg = nil @debug = false @hash = {} update_hash(ast.tree.body) end |
Instance Attribute Details
#debug=(value) ⇒ Object (writeonly)
debugging mode is on if true.
40 41 42 |
# File 'lib/yadriggy/syntax.rb', line 40 def debug=(value) @debug = value end |
#hash ⇒ Hash (readonly)
Returns the grammar rules.
37 38 39 |
# File 'lib/yadriggy/syntax.rb', line 37 def hash @hash end |
Class Method Details
.check_syntax(block) ⇒ Boolean
Checks the syntax of the grammar rules.
49 50 51 |
# File 'lib/yadriggy/syntax.rb', line 49 def self.check_syntax(block) @syntax.nil? || @syntax.check(block) end |
.last_error ⇒ String
Returns the error message for the grammar rule last checked.
55 56 57 |
# File 'lib/yadriggy/syntax.rb', line 55 def self.last_error @syntax.error end |
.ruby_syntax ⇒ Syntax
Defines Ruby syntax and returns its Syntax object.
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
# File 'lib/yadriggy/syntax.rb', line 455 def self.ruby_syntax Yadriggy.define_syntax do expr <= Name | Number | Super | Binary | Unary | SymbolLiteral | ConstPathRef | StringLiteral | StringInterpolation | ArrayLiteral | Paren | Call | ArrayRef | HashLiteral | Return | ForLoop | Loop | Conditional | Break | Lambda | BeginEnd | Def | ModuleDef exprs <= Exprs | expr Name <= { name: String } Number <= { value: Numeric } Super <= {} Identifier <= Name SymbolLiteral <= { name: String } VariableCall <= Name InstanceVariable <= Name GlobalVariable <= Name Label <= Name Reserved <= Name Const <= Name Binary <= { left: expr, op: Symbol, right: expr } ArrayRef <= { array: expr, indexes: [ expr ] } ArrayRefField <= ArrayRef Assign <= Binary Dots <= Binary Unary <= { op: Symbol, operand: expr } ConstPathRef <= { scope: (ConstPathRef | Const), name: Const } ConstPathField <= ConstPathRef StringLiteral <= { value: String } StringInterpolation <= { contents: [ exprs ] } ArrayLiteral <= { elements: [ expr ] } Paren <= { expression: expr } HashLiteral <= { pairs: [ expr * expr ] } Return <= { values: [ expr ] } ForLoop <= {vars: [ Identifier ], set: expr, body: exprs } Loop <= { op: Symbol, cond: expr, body: exprs } Conditional <= { op: Symbol, cond: expr, then: exprs, all_elsif: [expr * exprs], else: (exprs) } Parameters <= { params: [ Identifier ], optionals: [ Identifier * expr ], rest_of_params: (Identifier), params_after_rest: [ Identifier ], keywords: [ Label * expr ], rest_of_keywords: (Identifier), block_param: (Identifier) } Block <= Parameters + { body: exprs } Lambda <= Block Call <= { receiver: (expr), op: (Symbol), name: Identifier, args: [ expr ], block_arg: (expr), block: (Block) } Command <= Call Exprs <= { expressions: [ expr ] } Rescue <= { types: [ Const | ConstPathRef ], parameter: (Identifier), body: (exprs), nested_rescue: (Rescue), else: (exprs), ensure: (exprs) } BeginEnd <= { body: exprs, rescue: (Rescue) } Def <= Parameters + { singular: (expr), name: Identifier, body: exprs, rescue: (Rescue) } ModuleDef <= { name: Const | ConstPathRef, body: exprs, rescue: (Rescue) } ClassDef <= ModuleDef + { superclass: (Const | ConstPathRef) } SingularClassDef <= { name: expr, body: exprs, rescue: (Rescue) } Program <= { elements: exprs } end end |
Instance Method Details
#add_rules(syntax = nil) { ... } ⇒ Object
Adds rules.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/yadriggy/syntax.rb', line 89 def add_rules(syntax=nil, &block) if syntax.is_a?(Syntax) syntax.hash.each do |k,v| @hash[k] = v end elsif block.is_a?(Proc) ast = Yadriggy::reify(block) if Syntax.check_syntax(ast.tree) update_hash(ast.tree.body) else raise Syntax.last_error end end end |
#check(tree) ⇒ Boolean
Checks the syntax of the given AST.
118 119 120 121 122 123 124 125 126 |
# File 'lib/yadriggy/syntax.rb', line 118 def check(tree) error_cleared! expr = find_hash_entry(tree.class) if expr check_expr(expr, tree, false) || error_found!(tree, tree) else error_found!(tree, tree, "no rule for #{tree.class}") end end |
#check_error(astree) ⇒ void
This method returns an undefined value.
Checks the syntax of the given AST and raise an error if a syntax error is found.
110 111 112 |
# File 'lib/yadriggy/syntax.rb', line 110 def check_error(astree) raise_error unless check(astree.is_a?(ASTree) ? astree.tree : astree) end |
#check_usertype(user_type, tree) ⇒ Boolean
Checks whether the given AST matches the grammar rule for the given user type.
134 135 136 137 |
# File 'lib/yadriggy/syntax.rb', line 134 def check_usertype(user_type, tree) error_cleared! check_rule_usertype(user_type.to_s, tree, false) end |
#error ⇒ String
Returns an error message.
142 143 144 145 146 147 148 |
# File 'lib/yadriggy/syntax.rb', line 142 def error if @error_loc.nil? && @error_msg.nil? '' else "#{@error_loc} DSL syntax error#{@error_msg}" end end |
#raise_error ⇒ Object
Raises a syntax-error exception.
152 153 154 |
# File 'lib/yadriggy/syntax.rb', line 152 def raise_error raise SyntaxError.new(error) end |
#update_hash(body) ⇒ void
This method returns an undefined value.
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/yadriggy/syntax.rb', line 71 def update_hash(body) return if body.nil? if body.is_a?(Binary) key = to_hash_key(body.left) @hash[key] = body.right else body.expressions.each do |e| @hash[to_hash_key(e.left)] = e.right end end end |