# Treetop (http://treetop.rubyforge.org/) grammar for package definitions in v1 # format. # Some aspects of this grammar are significantly dumber than they could be # because: # # * We want to treat statements as identically as possible to their # command-line equivalents. # * Treetop parse errors are pretty inscrutable at times and we can make # error messages clearer by validating a lot of the terminals ourselves. require 'treetop' require 'fig/grammar/base' require 'fig/grammar/version' module Fig module Grammar grammar V1 include Fig::Grammar::Base include Fig::Grammar::Version rule package optional_ws_or_comment grammar_version:grammar_version? statements:(package_statement_with_ws*) optional_ws_or_comment { def to_package(directory, build_state) return build_state.new_package_statement( directory, grammar_version, statements ) end } end # Shim between "package" and "package_statement" rules to allow the # compiled v0 and v1 grammars to have the same interface. rule package_statement_with_ws package_statement:package_statement ws_or_comment+ { def to_package_statement(build_state) return package_statement.to_package_statement(build_state) end } end rule package_statement archive / resource / retrieve / config end rule archive statement_start:'archive' ws_or_comment+ url:asset_url { def to_package_statement(build_state) return build_state.new_asset_statement( Statement::Archive, statement_start, url ) end } end rule resource statement_start:'resource' ws_or_comment+ url:asset_url { def to_package_statement(build_state) return build_state.new_asset_statement( Statement::Resource, statement_start, url ) end } end rule asset_url '"' [^"]* '"' / "'" [^']* "'" / [\S]+ end rule retrieve statement_start:'retrieve' ws_or_comment+ var:environment_variable_name '->' path:retrieve_path { def to_package_statement(build_state) return build_state.new_retrieve_statement(statement_start, var, path) end } end rule retrieve_path [a-zA-Z0-9_/.\[\]-]+ end rule config statement_start:'config' ws_or_comment+ config_name ws_or_comment+ statements:config_statement_with_ws* 'end' { def to_package_statement(build_state) return build_state.new_configuration_statement( statement_start, config_name, statements ) end } end rule config_name [a-zA-Z0-9_.-]+ end # Shim between "config" and "config_statement" rules to allow the # compiled v0 and v1 grammars to have the same interface. rule config_statement_with_ws config_statement:config_statement ws_or_comment+ { def to_config_statement(build_state) return config_statement.to_config_statement(build_state) end } end rule config_statement override / include / command / path / set end rule include statement_start:'include' ws_or_comment+ descriptor_string { def to_config_statement(build_state) return build_state.new_include_statement( statement_start, descriptor_string ) end } end rule override statement_start:'override' ws_or_comment+ descriptor_string { def to_config_statement(build_state) return build_state.new_override_statement( statement_start, descriptor_string ) end } end rule path statement_start:('add' / 'append' / 'path') ws_or_comment+ name_value:[\S]+ { def to_config_statement(build_state) return build_state.new_environment_variable_statement( Statement::Path, statement_start, name_value ) end } end rule environment_variable_name [a-zA-Z0-9_]+ end rule set statement_start:'set' ws_or_comment+ name_value:[\S]+ { def to_config_statement(build_state) return build_state.new_environment_variable_statement( Statement::Set, statement_start, name_value ) end } end rule command statement_start:'command' ws_or_comment+ string { def to_config_statement(build_state) return build_state.new_command_statement(statement_start, string) end } end rule string '"' value:[^"]* '"' end rule descriptor_string [\S]+ end end end end