The lexer maintains a stack of last seen comments.
Each AST nodes has a doc property that is filled with the
last seen comments on node creation (in fact only on important node
creation representing statements).
Signed-off-by: Brice Figureau <[EMAIL PROTECTED]>
---
lib/puppet/parser/ast.rb | 2 +
lib/puppet/parser/grammar.ra | 50 ++++---
lib/puppet/parser/lexer.rb | 42 ++++++-
lib/puppet/parser/parser.rb | 256 ++++++++++++++++++-----------------
lib/puppet/parser/parser_support.rb | 16 ++-
5 files changed, 212 insertions(+), 154 deletions(-)
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index ddf8852..ede3842 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -12,6 +12,8 @@ class Puppet::Parser::AST
include Puppet::Util::Errors
include Puppet::Util::MethodHelper
+ include Puppet::Util::Docs
+
attr_accessor :line, :file, :parent, :scope
# Does this ast object set something? If so, it gets evaluated first.
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 23c2934..d01ab61 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -77,26 +77,28 @@ fstatement: NAME LPAREN funcvalues RPAREN {
result = ast AST::Function,
:name => val[0],
:arguments => args,
- :ftype => :statement
+ :ftype => :statement,
+ :doc => @lexer.getcomment
}
| NAME LPAREN funcvalues COMMA RPAREN {
args = aryfy(val[2])
result = ast AST::Function,
:name => val[0],
:arguments => args,
- :ftype => :statement
+ :ftype => :statement,
+ :doc => @lexer.getcomment
} | NAME LPAREN RPAREN {
result = ast AST::Function,
:name => val[0],
:arguments => AST::ASTArray.new({}),
- :ftype => :statement
+ :ftype => :statement, :doc => @lexer.getcomment
}
| NAME funcvalues {
args = aryfy(val[1])
result = ast AST::Function,
:name => val[0],
:arguments => args,
- :ftype => :statement
+ :ftype => :statement, :doc => @lexer.getcomment
}
funcvalues: namestring
@@ -146,19 +148,19 @@ resource: classname LBRACE resourceinstances
endsemi RBRACE {
result.push ast(AST::Resource,
:type => val[0],
:title => instance[0],
- :params => instance[1])
+ :params => instance[1], :doc => @lexer.getcomment)
}
} | classname LBRACE params endcomma RBRACE {
# This is a deprecated syntax.
error "All resource specifications require names"
} | classref LBRACE params endcomma RBRACE {
# a defaults setting for a type
- result = ast(AST::ResourceDefaults, :type => val[0], :params => val[2])
+ result = ast(AST::ResourceDefaults, :type => val[0], :params => val[2],
:doc => @lexer.getcomment)
}
# Override a value set elsewhere in the configuration.
resourceoverride: resourceref LBRACE anyparams endcomma RBRACE {
- result = ast AST::ResourceOverride, :object => val[0], :params => val[2]
+ result = ast AST::ResourceOverride, :object => val[0], :params => val[2],
:doc => @lexer.getcomment
}
# Exported and virtual resources; these don't get sent to the client
@@ -198,7 +200,7 @@ collection: classref collectrhand {
Puppet.warning addcontext("Collection names must now be capitalized")
end
type = val[0].downcase
- args = {:type => type}
+ args = {:type => type, :doc => @lexer.getcomment }
if val[1].is_a?(AST::CollExpr)
args[:query] = val[1]
@@ -303,12 +305,12 @@ assignment: VARIABLE EQUALS expression {
end
# this is distinct from referencing a variable
variable = ast AST::Name, :value => val[0]
- result = ast AST::VarDef, :name => variable, :value => val[2]
+ result = ast AST::VarDef, :name => variable, :value => val[2], :doc =>
@lexer.getcomment
}
append: VARIABLE APPENDS expression {
variable = ast AST::Name, :value => val[0]
- result = ast AST::VarDef, :name => variable, :value => val[2], :append =>
true
+ result = ast AST::VarDef, :name => variable, :value => val[2], :append =>
true, :doc => @lexer.getcomment
}
params: # nothing
@@ -412,7 +414,8 @@ resourceref: NAME LBRACK rvalues RBRACK {
ifstatement: IF expression LBRACE statements RBRACE else {
args = {
:test => val[1],
- :statements => val[3]
+ :statements => val[3],
+ :doc => @lexer.getcomment
}
if val[5]
@@ -424,7 +427,8 @@ ifstatement: IF expression LBRACE statements RBRACE
else {
| IF expression LBRACE RBRACE else {
args = {
:test => val[1],
- :statements => ast(AST::Nop)
+ :statements => ast(AST::Nop),
+ :doc => @lexer.getcomment
}
if val[4]
@@ -436,10 +440,10 @@ ifstatement: IF expression LBRACE statements RBRACE
else {
else: # nothing
| ELSE LBRACE statements RBRACE {
- result = ast AST::Else, :statements => val[2]
+ result = ast AST::Else, :statements => val[2], :doc => @lexer.getcomment
}
| ELSE LBRACE RBRACE {
- result = ast AST::Else, :statements => ast(AST::Nop)
+ result = ast AST::Else, :statements => ast(AST::Nop), :doc =>
@lexer.getcomment
}
# Unlike yacc/bison, it seems racc
@@ -512,7 +516,7 @@ casestatement: CASE rvalue LBRACE caseopts RBRACE {
unless options.instance_of?(AST::ASTArray)
options = ast AST::ASTArray, :children => [val[3]]
end
- result = ast AST::CaseStatement, :test => val[1], :options => options
+ result = ast AST::CaseStatement, :test => val[1], :options => options,
:doc => @lexer.getcomment
}
caseopts: caseopt
@@ -545,7 +549,7 @@ casevalues: selectlhand
}
selector: selectlhand QMARK svalues {
- result = ast AST::Selector, :param => val[0], :values => val[2]
+ result = ast AST::Selector, :param => val[0], :values => val[2], :doc =>
@lexer.getcomment
}
svalues: selectval
@@ -587,19 +591,19 @@ import: IMPORT qtexts {
import(file)
end
- result = AST::ASTArray.new(:children => [])
+ result = AST::ASTArray.new(:children => [], :doc => @lexer.getcomment)
}
# Disable definition inheritance for now. 8/27/06, luke
#definition: DEFINE NAME argumentlist parent LBRACE statements RBRACE {
definition: DEFINE classname argumentlist LBRACE statements RBRACE {
- newdefine classname(val[1]), :arguments => val[2], :code => val[4]
+ newdefine classname(val[1]), :arguments => val[2], :code => val[4], :doc
=> @lexer.getcomment
@lexer.indefine = false
result = nil
#} | DEFINE NAME argumentlist parent LBRACE RBRACE {
} | DEFINE classname argumentlist LBRACE RBRACE {
- newdefine classname(val[1]), :arguments => val[2]
+ newdefine classname(val[1]), :arguments => val[2], :doc =>
@lexer.getcomment
@lexer.indefine = false
result = nil
}
@@ -608,20 +612,20 @@ definition: DEFINE classname argumentlist LBRACE
statements RBRACE {
hostclass: CLASS classname classparent LBRACE statements RBRACE {
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :code => val[4], :parent => val[2]
+ newclass classname(val[1]), :code => val[4], :parent => val[2], :doc =>
@lexer.getcomment
result = nil
} | CLASS classname classparent LBRACE RBRACE {
# Our class gets defined in the parent namespace, not our own.
@lexer.namepop
- newclass classname(val[1]), :parent => val[2]
+ newclass classname(val[1]), :parent => val[2], :doc => @lexer.getcomment
result = nil
}
nodedef: NODE hostnames nodeparent LBRACE statements RBRACE {
- newnode val[1], :parent => val[2], :code => val[4]
+ newnode val[1], :parent => val[2], :code => val[4], :doc =>
@lexer.getcomment
result = nil
} | NODE hostnames nodeparent LBRACE RBRACE {
- newnode val[1], :parent => val[2]
+ newnode val[1], :parent => val[2], :doc => @lexer.getcomment
result = nil
}
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 9226434..4ff2d25 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -17,7 +17,7 @@ class Puppet::Parser::Lexer
# Our base token class.
class Token
- attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text
+ attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text,
:accumulate
def initialize(regex, name)
if regex.is_a?(String)
@@ -32,6 +32,10 @@ class Puppet::Parser::Lexer
self.skip
end
+ def accumulate?
+ self.accumulate
+ end
+
def to_s
if self.string
@string
@@ -155,7 +159,10 @@ class Puppet::Parser::Lexer
[string_token, value]
end
- TOKENS.add_token :COMMENT, %r{#.*}, :skip => true
+ TOKENS.add_token :COMMENT, %r{#.*}, :accumulate => true, :skip => true do
|lexer,value|
+ value.sub!('#','')
+ [self, value]
+ end
TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true,
:skip_text => true
@@ -320,6 +327,7 @@ class Puppet::Parser::Lexer
@namestack = []
@indefine = false
@expected = []
+ @commentstack = ['']
end
# Make any necessary changes to the token and/or value.
@@ -328,12 +336,18 @@ class Puppet::Parser::Lexer
skip() if token.skip_text
- return if token.skip
+ return if token.skip and not token.accumulate?
token, value = token.convert(self, value) if
token.respond_to?(:convert)
return unless token
+ if token.accumulate?
+ @commentstack.last << value+"\n"
+ end
+
+ return if token.skip
+
return token, value
end
@@ -388,6 +402,13 @@ class Puppet::Parser::Lexer
next unless final_token
+ # push comments on block change
+ if final_token.name == :LBRACE
+ commentpush('')
+ elsif final_token.name == :RBRACE
+ commentpop
+ end
+
if match = @@pairs[value] and final_token.name != :DQUOTE and
final_token.name != :SQUOTE
@expected << match
elsif exp = @expected[-1] and exp == value and final_token.name !=
:DQUOTE and final_token.name != :SQUOTE
@@ -448,4 +469,19 @@ class Puppet::Parser::Lexer
def string=(string)
@scanner = StringScanner.new(string)
end
+
+ # returns the content of the currently accumulated content cache
+ def commentpop
+ return @commentstack.pop
+ end
+
+ def getcomment
+ comment = @commentstack.pop
+ @commentstack.push('')
+ return comment
+ end
+
+ def commentpush(value)
+ @commentstack.push(value)
+ end
end
--
1.6.0.2
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---