def parse_stmt_list
list = []
while (method_symbol = METHOD_DISPATHER[token()]) != nil do
node = self.__send__(method_symbol)
if method_symbol == :parse_stmt_load
nodelist = node
list.concat(nodelist.list)
else
stmt_node = node
list << stmt_node
end
end
return NodeList.new(list)
end
def parse_stmt_set
Kwartz::assert() unless token() == :set
scan()
_syntaxerr("':set' requires '('.") unless token() == '('
scan()
expr = parse_assignment()
_syntaxerr("':set(' is not closed by ')'.") unless token() == ')'
scan()
_syntaxerr("':set' requires assignment.") unless _assign_op?(expr.token)
return SetStmtNode.new(:set, expr, nil)
end
def parse_stmt_if
Kwartz::assert() unless token() == :if || token() == :elsif
t = token()
scan()
_syntaxerr("':#{t.id2name}' requires '('.") unless token() == '('
scan()
cond_expr = parse_expression()
_syntaxerr("':#{t.id2name}(' is not closed by ')'.") unless token() == ')'
scan()
then_node = parse_stmt_list()
else_node = nil
if token() == :elsif
else_node = parse_stmt_if()
else
if token() == :else
scan()
else_node = parse_stmt_list()
end
_syntaxerr("':else' is not closed by ':end'.") unless token() == :end
scan()
end
return IfStmtNode.new(:if, then_node, else_node, cond_expr)
end
def parse_stmt_while
Kwartz::assert() unless token() == :while
scan()
_syntaxerr("':while' requires '('.") unless token() == '('
scan()
cond_expr = parse_assignment()
_syntaxerr("':while(' is not closed.") unless token() == ')'
scan()
nodelist = parse_stmt_list()
_syntaxerr("':while' is not closed by ':end'.") unless token() == :end
scan()
return WhileStmtNode.new(:while, nodelist, nil, cond_expr)
end
def parse_stmt_foreach
Kwartz::assert() unless token() == :foreach
scan()
_syntaxerr("':foreach' requires '('.") unless token() == '('
scan()
assign_expr = parse_assignment(true)
_syntaxerr("':foreach(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':foreach' requires assignment.") unless assign_expr.token == '='
nodelist = parse_stmt_list()
_syntaxerr("':foreach' is not closed by ':end'.") unless token() == :end
scan()
return ForeachStmtNode.new(:foreach, assign_expr, nodelist)
end
def parse_stmt_print
Kwartz::assert() unless token() == :print
scan()
_syntaxerr("':print' requires '('.") unless token() == '('
scan()
arg_expr = parse_expression()
while token() == ',' do
scan()
arg_expr2 = parse_expression()
arg_expr = ExprNode.new(',', arg_expr, arg_expr2)
end
_syntaxerr("':print(' is not closed.") unless token() == ')'
scan()
return PrintStmtNode.new(:print, arg_expr, nil)
end
def parse_stmt_macro
Kwartz::assert() unless token() == :macro || token() == :elem
scan()
_syntaxerr("':macro' requires '('.") unless token() == '('
scan()
name_expr = parse_expression()
_syntaxerr("':macro(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':macro' requires a name.") unless name_expr.token == :variable
name = name_expr.left
nodelist = parse_stmt_list()
_syntaxerr("':macro' is not closed by ':end'.") unless token() == :end
scan()
return MacroStmtNode.new(:macro, name, nodelist)
end
def parse_stmt_elem
Kwartz::assert() unless token() == :elem
scan()
_syntaxerr("':elem' requires '('.") unless token() == '('
scan()
name_expr = parse_expression()
_syntaxerr("':elem(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':elem' requires an element name.") unless name_expr.token == :variable
name = name_expr.left
_push_element_name(name)
nodelist = parse_stmt_list()
_syntaxerr("':elem' is not closed by ':end'.") unless token() == :end
_pop_element_name()
scan()
return MacroStmtNode.new(:macro, 'elem_' + name, nodelist)
end
def parse_stmt_expand
Kwartz::assert() unless token() == :expand
scan()
_syntaxerr("':expand' requires '('.") unless token() == '('
scan()
name_expr = parse_expression()
_syntaxerr("':expand(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':macro' requires a name.") unless name_expr.token == :variable
name = name_expr.left
return ExpandStmtNode.new(:expand, name, nil)
end
def parse_stmt_expand2
Kwartz::assert() unless token() == :expand2
macro_name = token_str()
scan()
return ExpandStmtNode.new(:expand, macro_name, nil)
end
def parse_stmt_specialexpand
Kwartz::assert() unless token() == :stag || token() == :cont || token() == :etag
elem_name = _element_name()
unless elem_name
msg = "@stag, @cont or @etag must be in :elem() statement."
raise SemanticError.new(msg)
end
macro_name = "#{token_str()}_#{elem_name}"
scan()
return ExpandStmtNode.new(:expand, macro_name, nil)
end
def parse_stmt_value
Kwartz::assert() unless token() == :value
scan()
_syntaxerr("':value' requires '('.") unless token() == '('
scan()
assign_expr = parse_assignment()
_syntaxerr("':value(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':value' requires assignment.") unless assign_expr.token == '='
name_expr = assign_expr.left
_syntaxerr("':value' requires a name.") unless name_expr.token == :variable
name = name_expr.left
expr = assign_expr.right
print_stmt = PrintStmtNode.new(:print, expr, nil)
nodelist = NodeList.new([print_stmt])
return MacroStmtNode.new(:macro, 'cont_' + name, nodelist)
end
def parse_stmt_rawcode
t = token()
if t == ':::'
str = token_str()
elsif t == :rawcode
scan()
_syntaxerr("':rawcode' needs '('.") unless token() == '('
scan()
expr = parse_expression()
_syntaxerr("':rawcode(' is not closed.") unless token() == ')'
_syntaxerr("':rawcode()' needs a string.") unless expr.token == :string
str = expr.left
end
scan()
return RawcodeStmtNode.new(:rawcode, str, nil)
end
def parse_stmt_load
Kwartz::assert() unless token() == :load
scan()
_syntaxerr("':load' requires '('.") unless token() == '('
scan()
filename_expr = parse_expression()
_syntaxerr("':load(' is not closed.") unless token() == ')'
scan()
_syntaxerr("':load' requires filename as a string.") unless filename_expr.token == :string
filename = filename_expr.left
@toppings[:load_path].each do |dir|
if test(?d, dir) && test(?f, "#{dir}/#{filename}")
filename = "#{dir}/#{filename}"
break
end
end if @toppings[:load_path]
unless test(?f, filename)
msg = "'#{filename}': not found."
raise ParseError.new(msg)
end
plcode = File.open(filename) { |f| f.read }
nodelist = Kwartz::Helper.parse(plcode, @toppings)
return nodelist
end
def parse
nodelist = parse_stmt_list()
unless token() == nil
if token.is_a?(String)
s = "'#{token()}'"
else
case token()
when :name, :number
s = "'#{token_str()}'"
when :string
s = "\"'#{token_str()}'\""
else
s = token()
end
end
_syntaxerr("#{s}: invalid statement.")
end
macro_list = []
stmt_list = []
nodelist.each do |stmtnode|
if stmtnode.token == :macro
macro_list << stmtnode
else
stmt_list << stmtnode
end
end
return NodeList.new(macro_list + stmt_list)
end
end