summaryrefslogtreecommitdiff
path: root/test/racc/assets/nasl.y
diff options
context:
space:
mode:
Diffstat (limited to 'test/racc/assets/nasl.y')
-rw-r--r--test/racc/assets/nasl.y626
1 files changed, 626 insertions, 0 deletions
diff --git a/test/racc/assets/nasl.y b/test/racc/assets/nasl.y
new file mode 100644
index 0000000000..e68dd699f8
--- /dev/null
+++ b/test/racc/assets/nasl.y
@@ -0,0 +1,626 @@
+################################################################################
+# Copyright (c) 2011-2014, Tenable Network Security
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+################################################################################
+
+class Nasl::Grammar
+
+preclow
+ right ASS_EQ ADD_EQ SUB_EQ MUL_EQ DIV_EQ MOD_EQ SLL_EQ SRA_EQ SRL_EQ
+ left OR
+ left AND
+ left CMP_LT CMP_GT CMP_EQ CMP_NE CMP_GE CMP_LE SUBSTR_EQ SUBSTR_NE REGEX_EQ REGEX_NE
+ left BIT_OR
+ left BIT_XOR
+ left AMPERSAND
+ left BIT_SRA BIT_SRL BIT_SLL
+ left ADD SUB
+ left MUL DIV MOD
+ right NOT
+ right UMINUS BIT_NOT
+ right EXP
+ right INCR DECR
+prechigh
+
+# Tell the parser generator that we don't wish to use the result variable in the
+# action section of rules. Instead, the result of the rule will be the value of
+# evaluating the action block.
+options no_result_var
+
+# Tell the parser generator that we expect one shift/reduce conflict due to the
+# well-known dangling else problem. We could make the grammar solve this
+# problem, but this is how the NASL YACC file solves it, so we'll follow suit.
+expect 1
+
+rule
+ ##############################################################################
+ # Aggregate Statements
+ ##############################################################################
+
+ start : roots
+ { val[0] }
+ | /* Blank */
+ { [] }
+ ;
+
+ roots : root roots
+ { [val[0]] + val[1] }
+ | root
+ { [val[0]] }
+ ;
+
+ root : COMMENT export
+ { c(*val) }
+ | export
+ { val[0] }
+ | COMMENT function
+ { c(*val) }
+ | function
+ { val[0] }
+ | statement
+ { val[0] }
+ ;
+
+ statement : simple
+ { val[0] }
+ | compound
+ { val[0] }
+ ;
+
+ ##############################################################################
+ # Root Statements
+ ##############################################################################
+
+ export : EXPORT function
+ { n(:Export, *val) }
+ ;
+
+ function : FUNCTION ident LPAREN params RPAREN block
+ { n(:Function, *val) }
+ | FUNCTION ident LPAREN RPAREN block
+ { n(:Function, *val) }
+ ;
+
+ simple : assign
+ { val[0] }
+ | break
+ { val[0] }
+ | call
+ { val[0] }
+ | continue
+ { val[0] }
+ | decr
+ { val[0] }
+ | empty
+ { val[0] }
+ | COMMENT global
+ { c(*val) }
+ | global
+ { val[0] }
+ | import
+ { val[0] }
+ | include
+ { val[0] }
+ | incr
+ { val[0] }
+ | local
+ { val[0] }
+ | rep
+ { val[0] }
+ | return
+ { val[0] }
+ ;
+
+ compound : block
+ { val[0] }
+ | for
+ { val[0] }
+ | foreach
+ { val[0] }
+ | if
+ { val[0] }
+ | repeat
+ { val[0] }
+ | while
+ { val[0] }
+ ;
+
+ ##############################################################################
+ # Simple Statements
+ ##############################################################################
+
+ assign : assign_exp SEMICOLON
+ { val[0] }
+ ;
+
+ break : BREAK SEMICOLON
+ { n(:Break, *val) }
+ ;
+
+ call : call_exp SEMICOLON
+ { val[0] }
+ ;
+
+ continue : CONTINUE SEMICOLON
+ { n(:Continue, *val) }
+ ;
+
+ decr : decr_exp SEMICOLON
+ { val[0] }
+ ;
+
+ empty : SEMICOLON
+ { n(:Empty, *val) }
+ ;
+
+ global : GLOBAL var_decls SEMICOLON
+ { n(:Global, *val) }
+ ;
+
+ incr : incr_exp SEMICOLON
+ { val[0] }
+ ;
+
+ import : IMPORT LPAREN string RPAREN SEMICOLON
+ { n(:Import, *val) }
+ ;
+
+ include : INCLUDE LPAREN string RPAREN SEMICOLON
+ { n(:Include, *val) }
+ ;
+
+ local : LOCAL var_decls SEMICOLON
+ { n(:Local, *val) }
+ ;
+
+ rep : call_exp REP expr SEMICOLON
+ { n(:Repetition, *val[0..-1]) }
+ ;
+
+ return : RETURN expr SEMICOLON
+ { n(:Return, *val) }
+ | RETURN ref SEMICOLON
+ { n(:Return, *val) }
+ | RETURN SEMICOLON
+ { n(:Return, *val) }
+ ;
+
+ ##############################################################################
+ # Compound Statements
+ ##############################################################################
+
+ block : LBRACE statements RBRACE
+ { n(:Block, *val) }
+ | LBRACE RBRACE
+ { n(:Block, *val) }
+ ;
+
+ for : FOR LPAREN field SEMICOLON expr SEMICOLON field RPAREN statement
+ { n(:For, *val) }
+ ;
+
+ foreach : FOREACH ident LPAREN expr RPAREN statement
+ { n(:Foreach, val[0], val[1], val[3], val[5]) }
+ | FOREACH LPAREN ident IN expr RPAREN statement
+ { n(:Foreach, val[0], val[2], val[4], val[6]) }
+ ;
+
+ if : IF LPAREN expr RPAREN statement
+ { n(:If, *val) }
+ | IF LPAREN expr RPAREN statement ELSE statement
+ { n(:If, *val) }
+ ;
+
+ repeat : REPEAT statement UNTIL expr SEMICOLON
+ { n(:Repeat, *val) }
+ ;
+
+ while : WHILE LPAREN expr RPAREN statement
+ { n(:While, *val) }
+ ;
+
+ ##############################################################################
+ # Expressions
+ ##############################################################################
+
+ assign_exp : lval ASS_EQ expr
+ { n(:Assignment, *val) }
+ | lval ASS_EQ ref
+ { n(:Assignment, *val) }
+ | lval ADD_EQ expr
+ { n(:Assignment, *val) }
+ | lval SUB_EQ expr
+ { n(:Assignment, *val) }
+ | lval MUL_EQ expr
+ { n(:Assignment, *val) }
+ | lval DIV_EQ expr
+ { n(:Assignment, *val) }
+ | lval MOD_EQ expr
+ { n(:Assignment, *val) }
+ | lval SRL_EQ expr
+ { n(:Assignment, *val) }
+ | lval SRA_EQ expr
+ { n(:Assignment, *val) }
+ | lval SLL_EQ expr
+ { n(:Assignment, *val) }
+ ;
+
+ call_exp : lval LPAREN args RPAREN
+ { n(:Call, *val) }
+ | lval LPAREN RPAREN
+ { n(:Call, *val) }
+ ;
+
+ decr_exp : DECR lval
+ { n(:Decrement, val[0]) }
+ | lval DECR
+ { n(:Decrement, val[0]) }
+ ;
+
+ incr_exp : INCR lval
+ { n(:Increment, val[0]) }
+ | lval INCR
+ { n(:Increment, val[0]) }
+ ;
+
+ expr : LPAREN expr RPAREN
+ { n(:Expression, *val) }
+ | expr AND expr
+ { n(:Expression, *val) }
+ | NOT expr
+ { n(:Expression, *val) }
+ | expr OR expr
+ { n(:Expression, *val) }
+ | expr ADD expr
+ { n(:Expression, *val) }
+ | expr SUB expr
+ { n(:Expression, *val) }
+ | SUB expr =UMINUS
+ { n(:Expression, *val) }
+ | BIT_NOT expr
+ { n(:Expression, *val) }
+ | expr MUL expr
+ { n(:Expression, *val) }
+ | expr EXP expr
+ { n(:Expression, *val) }
+ | expr DIV expr
+ { n(:Expression, *val) }
+ | expr MOD expr
+ { n(:Expression, *val) }
+ | expr AMPERSAND expr
+ { n(:Expression, *val) }
+ | expr BIT_XOR expr
+ { n(:Expression, *val) }
+ | expr BIT_OR expr
+ { n(:Expression, *val) }
+ | expr BIT_SRA expr
+ { n(:Expression, *val) }
+ | expr BIT_SRL expr
+ { n(:Expression, *val) }
+ | expr BIT_SLL expr
+ { n(:Expression, *val) }
+ | incr_exp
+ { val[0] }
+ | decr_exp
+ { val[0] }
+ | expr SUBSTR_EQ expr
+ { n(:Expression, *val) }
+ | expr SUBSTR_NE expr
+ { n(:Expression, *val) }
+ | expr REGEX_EQ expr
+ { n(:Expression, *val) }
+ | expr REGEX_NE expr
+ { n(:Expression, *val) }
+ | expr CMP_LT expr
+ { n(:Expression, *val) }
+ | expr CMP_GT expr
+ { n(:Expression, *val) }
+ | expr CMP_EQ expr
+ { n(:Expression, *val) }
+ | expr CMP_NE expr
+ { n(:Expression, *val) }
+ | expr CMP_GE expr
+ { n(:Expression, *val) }
+ | expr CMP_LE expr
+ { n(:Expression, *val) }
+ | assign_exp
+ { val[0] }
+ | string
+ { val[0] }
+ | call_exp
+ { val[0] }
+ | lval
+ { val[0] }
+ | ip
+ { val[0] }
+ | int
+ { val[0] }
+ | undef
+ { val[0] }
+ | list_expr
+ { val[0] }
+ | array_expr
+ { val[0] }
+ ;
+
+ ##############################################################################
+ # Named Components
+ ##############################################################################
+
+ arg : ident COLON expr
+ { n(:Argument, *val) }
+ | ident COLON ref
+ { n(:Argument, *val) }
+ | expr
+ { n(:Argument, *val) }
+ | ref
+ { n(:Argument, *val) }
+ ;
+
+ kv_pair : string COLON expr
+ { n(:KeyValuePair, *val) }
+ | int COLON expr
+ { n(:KeyValuePair, *val) }
+ | ident COLON expr
+ { n(:KeyValuePair, *val) }
+ | string COLON ref
+ { n(:KeyValuePair, *val) }
+ | int COLON ref
+ { n(:KeyValuePair, *val) }
+ | ident COLON ref
+ { n(:KeyValuePair, *val) }
+ ;
+
+ kv_pairs : kv_pair COMMA kv_pairs
+ { [val[0]] + val[2] }
+ | kv_pair COMMA
+ { [val[0]] }
+ | kv_pair
+ { [val[0]] }
+ ;
+
+ lval : ident indexes
+ { n(:Lvalue, *val) }
+ | ident
+ { n(:Lvalue, *val) }
+ ;
+
+ ref : AT_SIGN ident
+ { n(:Reference, val[1]) }
+ ;
+
+ ##############################################################################
+ # Anonymous Components
+ ##############################################################################
+
+ args : arg COMMA args
+ { [val[0]] + val[2] }
+ | arg
+ { [val[0]] }
+ ;
+
+ array_expr : LBRACE kv_pairs RBRACE
+ { n(:Array, *val) }
+ | LBRACE RBRACE
+ { n(:Array, *val) }
+ ;
+
+ field : assign_exp
+ { val[0] }
+ | call_exp
+ { val[0] }
+ | decr_exp
+ { val[0] }
+ | incr_exp
+ { val[0] }
+ | /* Blank */
+ { nil }
+ ;
+
+ index : LBRACK expr RBRACK
+ { val[1] }
+ | PERIOD ident
+ { val[1] }
+ ;
+
+ indexes : index indexes
+ { [val[0]] + val[1] }
+ | index
+ { [val[0]] }
+ ;
+
+ list_elem : expr
+ { val[0] }
+ | ref
+ { val[0] }
+ ;
+
+ list_elems : list_elem COMMA list_elems
+ { [val[0]] + val[2] }
+ | list_elem
+ { [val[0]] }
+ ;
+
+ list_expr : LBRACK list_elems RBRACK
+ { n(:List, *val) }
+ | LBRACK RBRACK
+ { n(:List, *val) }
+ ;
+
+ param : AMPERSAND ident
+ { n(:Parameter, val[1], 'reference') }
+ | ident
+ { n(:Parameter, val[0], 'value') }
+ ;
+
+ params : param COMMA params
+ { [val[0]] + val[2] }
+ | param
+ { [val[0]] }
+ ;
+
+ statements : statement statements
+ { [val[0]] + val[1] }
+ | statement
+ { [val[0]] }
+ ;
+
+ var_decl : ident ASS_EQ expr
+ { n(:Assignment, *val) }
+ | ident ASS_EQ ref
+ { n(:Assignment, *val) }
+ | ident
+ { val[0] }
+ ;
+
+ var_decls : var_decl COMMA var_decls
+ { [val[0]] + val[2] }
+ | var_decl
+ { [val[0]] }
+ ;
+
+ ##############################################################################
+ # Literals
+ ##############################################################################
+
+ ident : IDENT
+ { n(:Identifier, *val) }
+ | REP
+ { n(:Identifier, *val) }
+ | IN
+ { n(:Identifier, *val) }
+ ;
+
+ int : INT_DEC
+ { n(:Integer, *val) }
+ | INT_HEX
+ { n(:Integer, *val) }
+ | INT_OCT
+ { n(:Integer, *val) }
+ | FALSE
+ { n(:Integer, *val) }
+ | TRUE
+ { n(:Integer, *val) }
+ ;
+
+ ip : int PERIOD int PERIOD int PERIOD int
+ { n(:Ip, *val) }
+
+ string : DATA
+ { n(:String, *val) }
+ | STRING
+ { n(:String, *val) }
+ ;
+
+ undef : UNDEF
+ { n(:Undefined, *val) }
+ ;
+end
+
+---- header ----
+
+require 'nasl/parser/tree'
+
+require 'nasl/parser/argument'
+require 'nasl/parser/array'
+require 'nasl/parser/assigment'
+require 'nasl/parser/block'
+require 'nasl/parser/break'
+require 'nasl/parser/call'
+require 'nasl/parser/comment'
+require 'nasl/parser/continue'
+require 'nasl/parser/decrement'
+require 'nasl/parser/empty'
+require 'nasl/parser/export'
+require 'nasl/parser/expression'
+require 'nasl/parser/for'
+require 'nasl/parser/foreach'
+require 'nasl/parser/function'
+require 'nasl/parser/global'
+require 'nasl/parser/identifier'
+require 'nasl/parser/if'
+require 'nasl/parser/import'
+require 'nasl/parser/include'
+require 'nasl/parser/increment'
+require 'nasl/parser/integer'
+require 'nasl/parser/ip'
+require 'nasl/parser/key_value_pair'
+require 'nasl/parser/list'
+require 'nasl/parser/local'
+require 'nasl/parser/lvalue'
+require 'nasl/parser/parameter'
+require 'nasl/parser/reference'
+require 'nasl/parser/repeat'
+require 'nasl/parser/repetition'
+require 'nasl/parser/return'
+require 'nasl/parser/string'
+require 'nasl/parser/undefined'
+require 'nasl/parser/while'
+
+---- inner ----
+
+def n(cls, *args)
+ begin
+ Nasl.const_get(cls).new(@tree, *args)
+ rescue
+ puts "An exception occurred during the creation of a #{cls} instance."
+ puts
+ puts "The arguments passed to the constructer were:"
+ puts args
+ puts
+ puts @tok.last.context
+ puts
+ raise
+ end
+end
+
+def c(*args)
+ n(:Comment, *args)
+ args[1]
+end
+
+def on_error(type, value, stack)
+ raise ParseException, "The language's grammar does not permit #{value.name} to appear here", value.context
+end
+
+def next_token
+ @tok = @tkz.get_token
+
+ if @first && @tok.first == :COMMENT
+ n(:Comment, @tok.last)
+ @tok = @tkz.get_token
+ end
+ @first = false
+
+ return @tok
+end
+
+def parse(env, code, path)
+ @first = true
+ @tree = Tree.new(env)
+ @tkz = Tokenizer.new(code, path)
+ @tree.concat(do_parse)
+end
+
+---- footer ----