Class: Rubycc::Rmake::Parser
- Inherits:
-
Object
- Object
- Rubycc::Rmake::Parser
- Defined in:
- lib/rubycc/rmake/parser.rb
Overview
Turns Makefile text into the raw model — variables plus explicit rules with
their recipes — that Makefile then resolves into suffix rules, phony
targets, the suffix list and a dependency graph. The parser accepts only
the constructs the mkmf corpus (test/fixtures/mkmf) actually emits:
variable assignments in all four flavours, backslash line continuation,
# comments, explicit rules (single and double colon, with tab recipes)
and the .c.o:-style two-suffix inference rules. Anything it cannot place
is a ParseError rather than a silent skip, so an unsupported Makefile fails
loudly instead of mis-building.
Constant Summary collapse
- NAME =
A variable name: letters, digits and underscore, not starting with a digit. mkmf never uses dotted or otherwise exotic names, so keeping this narrow is what lets a leading-dot line (
.PHONY:,.c.o:) fall through to rule handling instead of being mistaken for an assignment. /[A-Za-z_][A-Za-z0-9_]*/- ASSIGN =
An assignment is a name, optional spaces, then an operator anchored right after the name.
+=/?=/::=/:=are tried before bare=, and all of them before a rule's:can match, soall: dep(colon then space) is never read as:=. /\A[ \t]*(#{NAME})[ \t]*(\+=|\?=|::=|:=|=)(.*)\z/
Instance Attribute Summary collapse
-
#rules ⇒ Object
readonly
Returns the value of attribute rules.
-
#variables ⇒ Object
readonly
Returns the value of attribute variables.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(overrides: {}, defaults: {}) ⇒ Parser
constructor
overridesare command-line variable definitions (make'sVAR=valueoperands): they are seeded before parsing and win over any assignment the Makefile makes to the same name, which is make's rule that a command-line variable overrides a makefile variable. - #run(text) ⇒ Object
Constructor Details
#initialize(overrides: {}, defaults: {}) ⇒ Parser
overrides are command-line variable definitions (make's VAR=value
operands): they are seeded before parsing and win over any assignment the
Makefile makes to the same name, which is make's rule that a command-line
variable overrides a makefile variable. They are stored as simple
(already-expanded) variables so a := assignment referencing one during
the parse sees the command-line value.
defaults are POSIX's built-in variables (currently just MAKE): unlike
overrides they are ordinary variables once seeded, so a Makefile
assignment to the same name replaces them exactly as it would replace any
other pre-existing value. They are seeded first so an override (or a
Makefile assignment) to the same name still wins.
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/rubycc/rmake/parser.rb', line 43 def initialize(overrides: {}, defaults: {}) @variables = {} @rules = [] @order = 0 @current_rule = nil @expander = Expander.new(@variables) @overrides = overrides || {} (defaults || {}).each { |name, value| @variables[name] = Variable.new(:simple, value.to_s) } @overrides.each { |name, value| @variables[name] = Variable.new(:simple, value.to_s) } end |
Instance Attribute Details
#rules ⇒ Object (readonly)
Returns the value of attribute rules.
54 55 56 |
# File 'lib/rubycc/rmake/parser.rb', line 54 def rules @rules end |
#variables ⇒ Object (readonly)
Returns the value of attribute variables.
54 55 56 |
# File 'lib/rubycc/rmake/parser.rb', line 54 def variables @variables end |
Class Method Details
.parse(text, overrides: {}, defaults: {}) ⇒ Object
56 57 58 |
# File 'lib/rubycc/rmake/parser.rb', line 56 def self.parse(text, overrides: {}, defaults: {}) new(overrides: overrides, defaults: defaults).tap { |p| p.run(text) } end |
Instance Method Details
#run(text) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rubycc/rmake/parser.rb', line 60 def run(text) logical_lines(text).each do |content, kind, line_no| if kind == :recipe handle_recipe(content, line_no) else handle_normal(content, line_no) end end self end |