├── .gitignore ├── BugClasses.txt ├── README.md ├── blog.md ├── requirements.txt ├── turbo-f-0.json ├── valid.json └── vasilisk ├── __init__.py ├── clean_tests.sh ├── coverage ├── __init__.py ├── groups │ ├── .gitignore │ ├── .group.py.swp │ ├── group.py │ ├── handler.py │ ├── metrics.py │ └── recorder.py ├── iterative │ ├── handler.py │ ├── metrics.py │ └── recorder.py └── probabilistic │ ├── handler.py │ ├── metrics.py │ └── recorder.py ├── fuzzers ├── __init__.py ├── base.py ├── group.py ├── iterative.py ├── optimize.py ├── probablistic.py └── verify.py ├── grammars ├── __init__.py ├── base.py ├── dharma_grammar.py ├── grammar.py ├── iterative.py ├── optimize.py ├── probabilistic.py ├── settings.py ├── templates │ ├── actions.dg │ ├── controls.dg │ ├── dependencies │ │ ├── arguments.dg │ │ ├── array.dg │ │ ├── boolean.dg │ │ ├── buffer.dg │ │ ├── common.dg │ │ ├── dataview.dg │ │ ├── date.dg │ │ ├── globals.dg │ │ ├── intl.dg │ │ ├── map.dg │ │ ├── math.dg │ │ ├── number.dg │ │ ├── object.dg │ │ ├── reflect.dg │ │ ├── regexp.dg │ │ ├── set.dg │ │ ├── string.dg │ │ ├── symbol.dg │ │ ├── value.dg │ │ ├── weakmap.dg │ │ └── weakset.dg │ ├── old │ │ ├── control_flow.dg │ │ ├── ecma1.dg │ │ ├── es6.dg │ │ ├── es6.ebnf │ │ ├── es6.ebnf.1 │ │ ├── grammar.dg │ │ ├── lex.py │ │ ├── old.dg │ │ ├── old_values.dg │ │ └── semantics.dg │ └── variables.dg └── verify.py └── vasilisk.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.pyc 3 | venv/ 4 | case* 5 | turbo.cfg 6 | turbo/ 7 | crashes/ 8 | vasilisk/grammars/templates/old 9 | args.gn 10 | paper/ 11 | coverage_data 12 | *.profraw 13 | -------------------------------------------------------------------------------- /BugClasses.txt: -------------------------------------------------------------------------------- 1 | Type Confusion 2 | Optimization Failure / Buggy Optimization Pass 3 | Out of Bounds Memory Read 4 | Uninitialized Values 5 | TurboFan 6 | Wasm 7 | Improper Deserialization and Containerization Methods 8 | Improper IR Generation ie (bytecode generation bugs) 9 | Memory Corruption in JIT Pages 10 | crankshaft for jit (crankshaft bugs) 11 | Use After Free 12 | Use After Poison 13 | Memory Range Optimization 14 | nullptr derefs from failed type casts 15 | TurboFan and LiftOff Interactions 16 | Integer Overflow 17 | Deoptimization Bug 18 | 19 | We can grab a corpus of bugs from an issue tracker as our test cases for fuzzing 20 | 21 | 22 | 23 | 24 | Coverage metric that focuses on different passes, and instrument a very specific area of v8. Our means over AFL is specifyin g instrumentation. 25 | 26 | 27 | JS O1 O2 O3 O4 and looking at code gen, hamming distance and specific hchanges are important 28 | Angr Validator 29 | 30 | Better validation metric (differential fuzzing) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vasilisk 2 | 3 | ## Setup 4 | Add to .bashrc 5 | export D8_PATH=/path/to/v8/out/release/d8 6 | 7 | ## Write up 8 | -------------------------------------------------------------------------------- /blog.md: -------------------------------------------------------------------------------- 1 | # Vasilisk 2 | 3 | By Roy Xu and Sai Vegasena 4 | 5 | 6 | ## Background 7 | 8 | Fuzzing consists of randomized input generation to automate the process of finding crashes in programs. The probability of finding a crash increases as code coverage in the application increases. In a well formed fuzzing campaign, test cases are generated in an automatic, systematic way such that every iteration generates a greater likelihood of crashing. The structure of input for an application must also be taken into account during this process. 9 | 10 | The premise of our research was to fuzz the JavaScript engine V8 by generating valid inputs. Specifically our target was to apply grammars to generate code that would trigger the most optimizations in TurboFan, the JIT in V8. The feedback metric used to assess coverage in the JIT was the input’s change over time through all the optimization passes. Using this metric grammar that favors heavy optimization can be selected and mutated in future iterations. 11 | 12 | TurboFan design consists of bitcode being JITed to quality machine code through phases of optimization passes. It makes use of static type information to accurately convert bytecode to machine code. During this process the bitcode can be translated into an intermediate representation where traits like evaluation order, code elimination, allocations, and bounds checks can be analyzed. By parsing the nodes in the IR, conclusions can be drawn about how actively the JIT optimized our test cases, and allows for updates to our grammars accordingly. Building V8 with sanitizers like ASAN, and SANCOV allows for methodology to be tested and verified. 13 | 14 | ## Introduction 15 | 16 | The goal of our research was to develop a feedback metric to measure code coverage in the V8 JIT, and leverage a custom method of grammar generation that accurately handled this feedback. Furthermore, the grammar generation component also had to preserve the interactions between different concrete grammar test cases. Our solution to this problem seeks to provide insight into fuzzing large applications when symbolic execution is not valid for dynamic test case generation, developing performant code generation systems with grammars, and uncovering new properties about JIT compiler bugs. A system such as this is able to start with versatile JavaScript and nurture specific test cases that force the JIT to do more work at each optimization pass. 17 | 18 | At high level a scoring system was developed based off percent changes after a test case passed through every phase of optimization. Test cases are initially generated from a corpus of grammars. Grammars are scored from the concrete test cases generated from them, and grammars with high scores are more likely to get selected in the next iteration of test case generation. A system for mutating, and preserving concrete interactions between different grammars was developed through the idea of grouping which will be elaborated in the Design and Implementation section. 19 | 20 | ## Design and Implementation 21 | 22 | At the heart of our design is a coverage metric based on changes in number of optimization passes. We divide our fuzzing into a series of rounds focused on a different subset of grammar rules. These rules are progressively combined and scored at each stage. We distinguish between three variations of grammar rules: actions, variables, and controls. 23 | 24 | Actions are generic snippets of JavaScript that can be applied to a variable. Variables are the various ways that JavaScript objects can be initialized. Controls are different methods of changing the control flow of a generated grammar. Our current generation defines a subset of rules as five actions and a control. These are picked randomly from unique grammar files that contain all actions and controls. Since actions are applied to variables, the set of variables used in a round depends on the actions that we pick. For every action, we pick at least one corresponding variable. However, in cases where there are multiple actions relying on the same variable type, we pick a random number between one and the total number of reliant actions. In some cases, actions will share a variable and in others, each will have their own variable. To bring our variables together, we have the concept of interactions. Currently, these consist of addition, subtraction, multiplication, and division. Pairs of variables are assigned a random interaction to allow a resulting combination of all variables which can be returned and printed by V8. 25 | 26 | Fuzzing rounds start with a single action and control. A variable is generated for that action and the result is combined into valid Javascript. We cycle through our five actions before expanding our action depth to two. Our grammar generation now contains a combination of two actions. At each stage we keep track of the parent from which this generation originated from. For example, given a set of actions: {0, 1, 2}, the parent of this set would be the set {1, 2}. 27 | 28 | Initially, our fuzzer took advantage of the open source grammar generation library, Dharma. However, our unique requirements and procedure meant that writing our own grammar generation would result in much faster performance. To save computational time over the course of running the fuzzer, we initially “unravel” our grammars. We look into the master lists of actions, variables, and controls and expand them out as far as we can while still being deterministic on startup. Usually this means we avoid extending to a point where we believe we are generating some end value. For example, if an action requires a random numerical value, we stop before generating it. When creating a fuzzing round, we pick a set of actions, variables, and controls from the unraveled grammar. This set must pass through another processing round where we fully expand out by choosing a random end value if necessary. 29 | As a result of our caching, we were able to vastly improve on generation time over dharma. 30 | 31 | Our framework itself consists of three parts: grammar generation, coverage, and our fuzzing instrumentation. Generated grammars are placed into a thread safe queue where our instrumentation running on different threads can ask for a grammar. A single thread handles generating the grammar, which has managed to keep up so far. The coverage portion of the framework coordinates between the grammar generation and the fuzzing itself. Our coverage information is stored in a redis db. When a grammar is generated we increment a counter in redis and when the grammar is processed by the fuzzing instrumentation we increment a separate counter. Before proceeding to a new round, we ensure that these counters match. 32 | 33 | When the fuzzing instrumentation finishes running a test case, we distinguish between results by exit codes. Timeouts and exit codes of 1 (V8 catches an error in the Javascript) are treated as invalid test cases and given a score of 0. All other exit codes are treated as a crash and given a very large score. Normal runs are passed along to the coverage portion along with the parent id of the generated grammar. A score is calculated as the sum of the changes between each optimization pass in TurboFan. If the parents score exists, that score is added to create a cumulative score. 34 | 35 | At the end of a fuzzing round we take the highest scoring set of rules (currently 10) and create a group for each. We call a set of actions, variables, controls, and interactions a group. These are currently stored as JSON and contain all the information necessary to recreate a test case. When our initial pool of groups reaches a point we determine to be impactful (~10,000), we move away from our progressive generation to a mutation based method. 36 | 37 | Each group allows for several mutations to be applied to it. For example, we may choose to change some interactions, replace an action, or regenerate an action if it relies on an end value. We compare each mutation to the base group and work towards eliciting more overall optimization passes. 38 | 39 | Our initial goal for fuzzing was to find ways to find ways to make TurboFan do more work. We hope that by eliciting more optimization passes, we can explore more of the TurboFan codebase as well as finding unique optimizations not normally created by fuzzers. By generating our grammars progressively, we focus on a growth in optimization passes instead of Javascript that generally produces more optimizations. We believe that this is a better method because we avoid being pushed towards working on only the same few rules over and over. In order to utilize our scoring, we decided to create groupings from our best results and mutate on them. 40 | 41 | ## Future Work 42 | 43 | There are certainly improvements to be made that would complement the design and scalability of vasilisk. With a larger corpus of initial grammars, vasilisk would be more robust with the ability to trigger more types of JIT optimizations with complicated language features. Furthermore, we could find a way to combine sets of grammars we already have to produce more interesting code after observing our first few trials with the fuzzer. Our current mechanism for re-scaling grammar weights was simply adding to the weight after each iteration. Implementing Q-learning would more aptly fit our use case, and adjust weights in a systematic way with less bias. This method would allow vasilisk to learn the effectiveness of grammars in a more meaningful, long term capacity. The mutations could also be improved within the groups. Perhaps developing more interactions and mechanics for relating variables to actions would complicate overall mutations positively. Furthermore, our current method of storing interesting test cases and crashes is writing to `/dev/shm`. An actual database where test cases could be properly deleted or mutated would promote less memory usage and greater scalability. A minor issue is that our variables grammar does not support variables within variables. Adding this would make mutations slightly more diverse. An interesting addition would also be to cache fuzzer runs and weights. Vasilisk could stop learning and store test cases and weights in a db. If it could then be restarted and pick off where it left off, it could continue to learn and update grammar weights instead of needing to start from scratch every time. We must also fix the bugs that were discovered during experimentation. Enhancing vasilisk to make better use of cpu resources and use as many cores as possible to their fullest, but as Vasilisk is written in python it makes working with threads at a more granular level more difficult. 44 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Click==7.0 2 | dharma==1.2.0 3 | PyExecJS==1.5.1 4 | redis==3.2.0 5 | six==1.12.0 6 | UgliPyJS==0.2.5 7 | -------------------------------------------------------------------------------- /vasilisk/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osirislab/vasilisk/5aa07c0cd58b8cd9fb776fa2cd13dc6d8f19ae0c/vasilisk/__init__.py -------------------------------------------------------------------------------- /vasilisk/clean_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -rf /tmp/vasilisk/tests 3 | -------------------------------------------------------------------------------- /vasilisk/coverage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osirislab/vasilisk/5aa07c0cd58b8cd9fb776fa2cd13dc6d8f19ae0c/vasilisk/coverage/__init__.py -------------------------------------------------------------------------------- /vasilisk/coverage/groups/.gitignore: -------------------------------------------------------------------------------- 1 | groups/* 2 | -------------------------------------------------------------------------------- /vasilisk/coverage/groups/.group.py.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osirislab/vasilisk/5aa07c0cd58b8cd9fb776fa2cd13dc6d8f19ae0c/vasilisk/coverage/groups/.group.py.swp -------------------------------------------------------------------------------- /vasilisk/coverage/groups/group.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import uuid 4 | 5 | 6 | def string_to_group(json_string): 7 | store_obj = json.loads(json_string) 8 | return Group(store_obj['a'], store_obj['v'], 9 | store_obj['c'], store_obj['i']) 10 | 11 | 12 | class Group(object): 13 | """ Expects a list of tuples in the format (grammar, 14 | concrete test case, rule)""" 15 | def __init__(self, actions_to_variables, resolved_variables, 16 | controls, interactions): 17 | self.actions = actions_to_variables 18 | self.variables = resolved_variables 19 | self.controls = controls 20 | self.interactions = interactions 21 | self.store_dir = os.path.join( 22 | os.path.abspath(os.path.dirname(__file__)), 'groups' 23 | ) 24 | if not os.path.exists(self.store_dir): 25 | os.makedirs(self.store_dir) 26 | 27 | def unpack(self): 28 | return [self.actions, 29 | self.variables, 30 | self.controls, 31 | self.interactions] 32 | 33 | def pack(self, elements): 34 | a, v, c, i = elements 35 | self.actions = a 36 | self.variables = v 37 | self.controls = c 38 | self.interactions = i 39 | 40 | def to_string(self): 41 | store_obj = { 42 | 'a': self.actions, 43 | 'v': self.variables, 44 | 'c': self.controls, 45 | 'i': self.interactions 46 | } 47 | 48 | return json.dumps(store_obj) 49 | 50 | def store(self): 51 | identifier = str(uuid.uuid4()) 52 | with open(os.path.join(self.store_dir, identifier), 'w+') as f: 53 | f.write(self.to_string()) 54 | 55 | return identifier 56 | 57 | def set_actions(self, actions): 58 | self.actions = actions 59 | 60 | def get_actions(self): 61 | return self.actions 62 | 63 | def set_variables(self, variables): 64 | self.variables = variables 65 | 66 | def get_variables(self): 67 | return self.variables 68 | 69 | def set_interactions(self, interactions): 70 | self.interactions = interactions 71 | 72 | def get_interactions(self): 73 | return self.interactions 74 | -------------------------------------------------------------------------------- /vasilisk/coverage/groups/handler.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import redis 4 | import subprocess 5 | 6 | from collections import Counter 7 | 8 | from .group import Group 9 | from .group import string_to_group 10 | 11 | 12 | class CoverageHandler(object): 13 | def __init__(self): 14 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 15 | decode_responses=True) 16 | 17 | self.redis.set('generated', 0) 18 | self.redis.set('processed', 0) 19 | self.logger = logging.getLogger(__name__) 20 | 21 | def reset(self): 22 | self.redis.set('generated', 0) 23 | self.redis.set('processed', 0) 24 | 25 | self.logger.info('Collect Scores') 26 | scores = Counter() 27 | for id in self.redis.lrange('finals', 0, -1): 28 | scores[id] = self.redis.get(f'score:{id}') 29 | 30 | for id, score in scores.most_common(100): 31 | self.redis.set(f'i_group:{id}', self.redis.get(f'group:{id}')) 32 | self.redis.set(f'i_score:{id}', self.redis.get(f'score:{id}')) 33 | self.redis.lpush('interesting', id) 34 | 35 | self.logger.info('Stored Interesting') 36 | while True: 37 | id = self.redis.lpop('finals') 38 | if not id: 39 | break 40 | self.redis.delete(f'group:{id}') 41 | self.redis.delete(f'score:{id}') 42 | 43 | 44 | self.logger.info('Delete Groups') 45 | self.condense_profraw() 46 | 47 | def up_to_date(self): 48 | if self.redis.get('generated') == self.redis.get('processed'): 49 | return True 50 | return False 51 | 52 | def store(self, id, actions, resolved_variables, 53 | controls, interactions, final=False): 54 | self.redis.incr('generated') 55 | if final: 56 | group = Group(actions, resolved_variables, 57 | controls, interactions) 58 | self.redis.lpush('finals', id) 59 | self.redis.set(f'group:{id}', group.to_string()) 60 | 61 | def store_group(self, group): 62 | self.redis.incr('generated') 63 | self.redis.lpush('mutate', group.to_string()) 64 | 65 | def get_most_interesting(self): 66 | scores = Counter() 67 | for id in self.redis.lrange('interesting', 0, -1): 68 | scores[id] = self.redis.get(f'i_score:{id}') 69 | 70 | interesting = [] 71 | for id, score in scores.most_common(100): 72 | interesting.append( 73 | string_to_group(self.redis.get(f'i_group:{id}'))) 74 | 75 | while True: 76 | id = self.redis.lpop('interesting') 77 | if not id: 78 | break 79 | self.redis.delete(f'i_group:{id}') 80 | self.redis.delete(f'i_score:{id}') 81 | 82 | return interesting 83 | 84 | def get_num_interesting(self): 85 | return self.redis.llen('interesting') 86 | 87 | def condense_profraw(self): 88 | coverage_folder = os.path.join(os.getcwd(), 'coverage_data') 89 | for file in os.listdir(coverage_folder): 90 | if not os.path.isfile(os.path.join(coverage_folder, file)): 91 | continue 92 | if file == 'vasilisk.profdata': 93 | continue 94 | cmd = ['llvm-profdata', 'merge', 95 | os.path.join(coverage_folder, 'vasilisk.profdata')] 96 | cmd.append(os.path.join(coverage_folder, file)) 97 | cmd += ['-o', os.path.join(coverage_folder, 'vasilisk.profdata')] 98 | try: 99 | subprocess.call(cmd) 100 | except Exception: 101 | pass 102 | os.remove(os.path.join(coverage_folder, file)) 103 | -------------------------------------------------------------------------------- /vasilisk/coverage/groups/metrics.py: -------------------------------------------------------------------------------- 1 | import redis 2 | 3 | 4 | class CoverageMetrics(object): 5 | def __init__(self): 6 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 7 | decode_responses=True) 8 | 9 | def print_records(self): 10 | pass 11 | 12 | 13 | if __name__ == '__main__': 14 | opt = CoverageMetrics() 15 | opt.print_records() 16 | -------------------------------------------------------------------------------- /vasilisk/coverage/groups/recorder.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import redis 4 | 5 | 6 | class CoverageRecorder: 7 | def __init__(self): 8 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 9 | decode_responses=True) 10 | 11 | def parse(self, turbo_json): 12 | with open(turbo_json, 'r') as f: 13 | turbo = json.loads(f.read()) 14 | 15 | skip = ['before register allocation', 'after register allocation', 16 | 'schedule', 'effect linearization schedule', 17 | 'select instructions', 'code generation', 'disassembly'] 18 | 19 | filtered = {} 20 | for phase in turbo['phases']: 21 | name = phase['name'] 22 | if name not in skip: 23 | filtered[name] = {} 24 | for node in phase['data']['nodes']: 25 | filtered[name][str(node['id'])] = node['title'] 26 | 27 | return filtered 28 | 29 | def metrics(self, turbo_json): 30 | turbo = self.parse(turbo_json) 31 | if turbo is None: 32 | return 0 33 | 34 | differences = {} 35 | prev = {} 36 | for phase, nodes in turbo.items(): 37 | if prev: 38 | differences[phase] = {'changes': 0, 39 | 'additions': 0, 40 | 'deletions': 0} 41 | for id, title in nodes.items(): 42 | if id not in prev: 43 | differences[phase]['additions'] += 1 44 | elif title != prev[id]: 45 | differences[phase]['changes'] += 1 46 | 47 | for id in prev.keys(): 48 | if id not in nodes: 49 | differences[phase]['deletions'] += 1 50 | 51 | prev = nodes 52 | 53 | total = 0 54 | for changes in differences.values(): 55 | total += sum(changes.values()) 56 | 57 | return total 58 | 59 | def found(self, id): 60 | self.redis.set(f'score:{id}', 9999) 61 | self.redis.incr('processed') 62 | 63 | def invalid(self, id): 64 | self.redis.set(f'score:{id}', 0) 65 | self.redis.incr('processed') 66 | 67 | def record(self, id, case, turbo_path): 68 | turbo_json = os.path.join(turbo_path, 'turbo-f-0.json') 69 | total = self.metrics(turbo_json) 70 | 71 | if ':' in id: 72 | parent_id = id[id.index(':') + 1:] 73 | total += int(self.redis.get(f'score:{parent_id}')) 74 | 75 | self.redis.set(f'score:{id}', total) 76 | self.redis.incr('processed') 77 | -------------------------------------------------------------------------------- /vasilisk/coverage/iterative/handler.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | import math 3 | import redis 4 | 5 | 6 | class CoverageHandler(object): 7 | def __init__(self): 8 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 9 | decode_responses=True) 10 | 11 | if not self.redis.exists('total'): 12 | self.redis.set('total', 0) 13 | 14 | if not self.redis.exists('saved'): 15 | self.redis.set('saved', 0) 16 | 17 | self.redis.set('count', 0) 18 | 19 | def comb_fmt(self, actions, controls): 20 | comb_str = 'comb:' 21 | comb_str += 'actions:' 22 | comb_str += ','.join(actions) 23 | comb_str += ';controls:' 24 | comb_str += ','.join(controls) 25 | return comb_str 26 | 27 | def case_fmt(self, actions, controls): 28 | comb_str = 'case:' 29 | comb_str += 'actions:' 30 | comb_str += ','.join(actions) 31 | comb_str += ';controls:' 32 | comb_str += ','.join(controls) 33 | return comb_str 34 | 35 | def store_fmt(self, actions, controls): 36 | comb_str = 'store:' 37 | comb_str += 'actions:' 38 | comb_str += ','.join(actions) 39 | comb_str += ';controls:' 40 | comb_str += ','.join(controls) 41 | return comb_str 42 | 43 | def unique(self, actions, controls): 44 | curr_comb = self.comb_fmt(actions, controls) 45 | combs = self.redis.lrange('combinations', 0, -1) 46 | for comb in combs: 47 | if curr_comb == comb: 48 | return False 49 | 50 | return True 51 | 52 | def score(self, actions, controls, action_depth, control_depth): 53 | totals = {} 54 | for control in controls: 55 | for i in range(action_depth): 56 | for action in itertools.product(actions, repeat=i+1): 57 | total = self.redis.get(self.case_fmt(action, [control])) 58 | totals[','.join(action)] = int(total) 59 | 60 | scores = {} 61 | cumulative = 0.0 62 | 63 | for action in actions: 64 | cumulative += totals[action] 65 | average = cumulative / len(actions) 66 | 67 | for action in actions: 68 | scores[action] = math.sqrt(abs(totals[action] - average)) 69 | 70 | for i in range(1, action_depth): 71 | for action in itertools.product(actions, repeat=i+1): 72 | action_key = ','.join(action) 73 | prev_action_key = ','.join(action[:-1]) 74 | change = abs(totals[action_key] - totals[prev_action_key]) 75 | scores[action_key] = (scores[prev_action_key] + 76 | math.sqrt(change)) 77 | 78 | for action in itertools.product(actions, repeat=len(actions)): 79 | score = scores[','.join(action)] 80 | total = float(self.redis.get('total')) 81 | saved = float(self.redis.get('saved')) 82 | if saved == 0: 83 | average = 0 84 | else: 85 | average = total / saved 86 | if score - average >= -1: 87 | self.redis.set('total', str(total + score)) 88 | self.redis.incr('saved') 89 | self.redis.set(self.store_fmt(action, controls), score) 90 | print(action, scores[','.join(action)]) 91 | 92 | def reset(self, actions, controls): 93 | self.redis.rpush('combinations', self.comb_fmt(actions, controls)) 94 | self.redis.set('count', 0) 95 | 96 | for case in self.redis.keys(pattern='case:*'): 97 | self.redis.delete(case) 98 | 99 | def get_count(self): 100 | return int(self.redis.get('count')) 101 | 102 | def get_saved(self): 103 | return int(self.redis.get('saved')) 104 | -------------------------------------------------------------------------------- /vasilisk/coverage/iterative/metrics.py: -------------------------------------------------------------------------------- 1 | import redis 2 | 3 | 4 | class CoverageMetrics(object): 5 | def __init__(self): 6 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 7 | decode_responses=True) 8 | 9 | def print_records(self): 10 | pass 11 | 12 | 13 | if __name__ == '__main__': 14 | opt = CoverageMetrics() 15 | opt.print_records() 16 | -------------------------------------------------------------------------------- /vasilisk/coverage/iterative/recorder.py: -------------------------------------------------------------------------------- 1 | # import os 2 | import random 3 | import redis 4 | 5 | 6 | class CoverageRecorder: 7 | def __init__(self): 8 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 9 | decode_responses=True) 10 | 11 | def case_fmt(self, actions, controls): 12 | case_str = 'case:' 13 | case_str += 'actions:' 14 | case_str += ','.join(actions) 15 | case_str += ';controls:' 16 | case_str += ','.join(controls) 17 | return case_str 18 | 19 | def metrics(self, turbo_json): 20 | turbo = self.parse(turbo_json) 21 | 22 | differences = {} 23 | prev = {} 24 | for phase, nodes in turbo.items(): 25 | if prev: 26 | differences[phase] = {'changes': 0, 27 | 'additions': 0, 28 | 'deletions': 0} 29 | for id, title in nodes.items(): 30 | if id not in prev: 31 | differences[phase]['additions'] += 1 32 | elif title != prev[id]: 33 | differences[phase]['changes'] += 1 34 | 35 | for id in prev.keys(): 36 | if id not in nodes: 37 | differences[phase]['deletions'] += 1 38 | 39 | prev = nodes 40 | 41 | return differences 42 | 43 | def record(self, case, turbo_path): 44 | # turbo_json = os.path.join(turbo_path, 'turbo-f-0.json') 45 | # total = 0 46 | # for changes in self.metrics(turbo_json).values(): 47 | # total += sum(changes.values()) 48 | total = random.randrange(30, 50) 49 | actions, controls = case 50 | 51 | for _ in range(len(actions)): 52 | total += random.randrange(0, 10) 53 | 54 | self.redis.set(self.case_fmt(actions, controls), total) 55 | self.redis.incr('count') 56 | -------------------------------------------------------------------------------- /vasilisk/coverage/probabilistic/handler.py: -------------------------------------------------------------------------------- 1 | import redis 2 | 3 | 4 | class CoverageHandler(object): 5 | def __init__(self, values, controls): 6 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 7 | decode_responses=True) 8 | 9 | if not self.redis.exists('count'): 10 | self.redis.set('count', 0) 11 | 12 | if not self.redis.exists('total'): 13 | self.redis.set('total', 0) 14 | 15 | self.count = int(self.redis.get('count')) 16 | self.cumulative_total = self.redis.get('total') 17 | self.average = 0 18 | if self.count != 0: 19 | self.average = float(self.cumulative_total) / self.count 20 | 21 | for rule in values.keys(): 22 | if not self.redis.exists('value:' + rule): 23 | self.redis.set('value:' + rule, 10) 24 | 25 | for rule in controls.keys(): 26 | if not self.redis.exists('control:' + rule): 27 | self.redis.set('control:' + rule, 10) 28 | 29 | def get_values(self): 30 | values = self.redis.keys(pattern='value:*') 31 | probabilities = {} 32 | for value in values: 33 | rule = value.split('value:')[1] 34 | probabilities[rule] = int(self.redis.get(value)) 35 | 36 | return probabilities 37 | 38 | def get_controls(self): 39 | controls = self.redis.keys(pattern='control:*') 40 | probabilities = {} 41 | for control in controls: 42 | rule = control.split('control:')[1] 43 | probabilities[rule] = int(self.redis.get(control)) 44 | 45 | return probabilities 46 | -------------------------------------------------------------------------------- /vasilisk/coverage/probabilistic/metrics.py: -------------------------------------------------------------------------------- 1 | import redis 2 | 3 | 4 | class CoverageMetrics(object): 5 | def __init__(self): 6 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 7 | decode_responses=True) 8 | 9 | self.count = int(self.redis.get('count')) 10 | self.cumulative_total = self.redis.get('total') 11 | self.average = float(self.cumulative_total) / self.count 12 | 13 | def print_records(self): 14 | print(f'{self.count} cases processed') 15 | print(f'{self.average} average changes') 16 | 17 | print('-' * 80) 18 | print('processed cases:') 19 | cases = self.redis.keys(pattern='case:*') 20 | for case in cases: 21 | print(case.split('case:')[1].split(','), self.redis.get(case)) 22 | 23 | print('-' * 80) 24 | print('scores for values:') 25 | values = self.redis.keys(pattern='value:*') 26 | for value in values: 27 | print(value.split('value:')[1], self.redis.get(value)) 28 | 29 | print('-' * 80) 30 | print('scores for controls') 31 | controls = self.redis.keys(pattern='control:*') 32 | for control in controls: 33 | print(control.split('control:')[1], self.redis.get(control)) 34 | 35 | 36 | if __name__ == '__main__': 37 | opt = CoverageMetrics() 38 | opt.print_records() 39 | -------------------------------------------------------------------------------- /vasilisk/coverage/probabilistic/recorder.py: -------------------------------------------------------------------------------- 1 | import json 2 | import math 3 | import os 4 | import redis 5 | 6 | 7 | class CoverageRecorder: 8 | def __init__(self): 9 | self.redis = redis.Redis(host='localhost', port=6379, db=0, 10 | decode_responses=True) 11 | 12 | self.max_score = 50 13 | self.min_score = 5 14 | 15 | def parse(self, turbo_json): 16 | with open(turbo_json, 'r') as f: 17 | turbo = json.loads(f.read()) 18 | 19 | skip = ['before register allocation', 'after register allocation', 20 | 'schedule', 'effect linearization schedule', 21 | 'select instructions', 'code generation', 'disassembly'] 22 | 23 | filtered = {} 24 | for phase in turbo['phases']: 25 | name = phase['name'] 26 | if name not in skip: 27 | filtered[name] = {} 28 | for node in phase['data']['nodes']: 29 | filtered[name][str(node['id'])] = node['title'] 30 | 31 | return filtered 32 | 33 | def metrics(self, turbo_json): 34 | turbo = self.parse(turbo_json) 35 | 36 | differences = {} 37 | prev = {} 38 | for phase, nodes in turbo.items(): 39 | if prev: 40 | differences[phase] = {'changes': 0, 41 | 'additions': 0, 42 | 'deletions': 0} 43 | for id, title in nodes.items(): 44 | if id not in prev: 45 | differences[phase]['additions'] += 1 46 | elif title != prev[id]: 47 | differences[phase]['changes'] += 1 48 | 49 | for id in prev.keys(): 50 | if id not in nodes: 51 | differences[phase]['deletions'] += 1 52 | 53 | prev = nodes 54 | 55 | return differences 56 | 57 | def record(self, grammars, turbo_path): 58 | turbo_json = os.path.join(turbo_path, 'turbo-f-0.json') 59 | total = 0 60 | for changes in self.metrics(turbo_json).values(): 61 | total += sum(changes.values()) 62 | 63 | case = 'case:' + ','.join(grammars) 64 | self.redis.set(case, total) 65 | self.redis.incr('count') 66 | cumulative_total = int(self.redis.get('total')) 67 | self.redis.set('total', str(cumulative_total + total)) 68 | count = int(self.redis.get('count')) 69 | average = float(cumulative_total) / count 70 | 71 | reward = math.floor(math.sqrt(abs(total - average))) - 2 72 | 73 | value = f'value:{grammars[0]}' 74 | control = f'control:{grammars[1]}' 75 | 76 | new_value = int(self.redis.get(value)) + reward 77 | new_value = max(new_value, self.min_score) 78 | new_value = min(new_value, self.max_score) 79 | 80 | new_control = int(self.redis.get(control)) + reward 81 | new_control = max(new_control, self.min_score) 82 | new_control = min(new_control, self.max_score) 83 | 84 | self.redis.set(value, str(new_value)) 85 | self.redis.set(control, str(new_control)) 86 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/__init__.py: -------------------------------------------------------------------------------- 1 | from .optimize import OptimizeFuzzer 2 | from .probablistic import ProbablisticFuzzer 3 | from .iterative import IterativeFuzzer 4 | from .verify import VerifyFuzzer 5 | from .group import GroupFuzzer 6 | 7 | fuzzers = {'optimize': OptimizeFuzzer, 8 | 'probabilistic': ProbablisticFuzzer, 9 | 'iterative': IterativeFuzzer, 10 | 'verify': VerifyFuzzer, 11 | 'groups': GroupFuzzer} 12 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/base.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from abc import ABC, abstractmethod 5 | 6 | 7 | class BaseFuzzer(ABC): 8 | def __init__(self): 9 | pass 10 | 11 | @abstractmethod 12 | def validate(self, output): 13 | pass 14 | 15 | @abstractmethod 16 | def fuzz(self, test_case): 17 | pass 18 | 19 | def create_test(self, test_case, file_name): 20 | """Takes generated test case and writes to file""" 21 | with open(os.path.join(self.tests, file_name), 'w+') as f: 22 | f.write(test_case) 23 | 24 | def commit_test(self, test_case, file_name): 25 | """Test case valuable, save to logs""" 26 | self.logger.info('found fuzzing target') 27 | 28 | case_folder = os.path.join(self.crashes, file_name) 29 | 30 | if os.path.exists(case_folder): 31 | self.logger.error('duplicate case folder') 32 | sys.exit(1) 33 | 34 | os.mkdir(case_folder) 35 | 36 | dest = os.path.join(case_folder, 'input') 37 | with open(dest, 'w+') as f: 38 | f.write(test_case) 39 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/group.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import subprocess 4 | import time 5 | import uuid 6 | 7 | from datetime import datetime 8 | 9 | from coverage.groups import recorder 10 | 11 | from .base import BaseFuzzer 12 | 13 | 14 | class GroupFuzzer(BaseFuzzer): 15 | def __init__(self, threads, d8, crashes, tests, debug, 16 | code_coverage=True): 17 | self.logger = logging.getLogger(__name__) 18 | 19 | self.d8 = d8 20 | self.crashes = crashes 21 | self.tests = tests 22 | self.debug = debug 23 | self.code_coverage = code_coverage 24 | 25 | coverage_dir = os.path.join('/dev/shm', 'vasilisk_coverage') 26 | if not os.path.exists(coverage_dir): 27 | self.logger.info('creating coverage dir') 28 | os.makedirs(coverage_dir) 29 | 30 | self.coverage_paths = [] 31 | for thread in range(threads): 32 | coverage_path = os.path.join( 33 | coverage_dir, 'thread-{}'.format(thread) 34 | ) 35 | self.coverage_paths.append(coverage_path) 36 | 37 | if not os.path.exists(coverage_path): 38 | self.logger.info('creating thread specific coverage dir') 39 | os.makedirs(coverage_path) 40 | 41 | self.coverage = recorder.CoverageRecorder() 42 | 43 | def execute(self, test_case, final, thread): 44 | options = ['--allow-natives-syntax', '--trace-turbo', 45 | '--trace-turbo-path', self.coverage_paths[thread], '-e'] 46 | 47 | cmd = ' '.join([self.d8] + options + [test_case]) 48 | if self.code_coverage and final: 49 | env_var = (f"LLVM_PROFILE_FILE={os.getcwd()}/coverage_data/" 50 | f"{time.time()}-{thread}.profraw") 51 | cmd = f"{env_var} {cmd}" 52 | 53 | self.logger.debug(cmd) 54 | try: 55 | return subprocess.check_output(cmd, shell=True, timeout=0.5) 56 | except subprocess.TimeoutExpired as e: 57 | self.logger.debug(e) 58 | return 'Invalid' 59 | except subprocess.CalledProcessError as e: 60 | if int(e.returncode) == 1: 61 | return 'Invalid' 62 | self.logger.error(e) 63 | return None 64 | 65 | def fuzz(self, test_case, thread): 66 | unique_id = None 67 | id, final, grammar = test_case 68 | 69 | output = self.execute(grammar, final, thread) 70 | 71 | self.logger.debug(output) 72 | 73 | status = self.validate(output) 74 | if status == 1: 75 | if unique_id is None: 76 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 77 | unique_id = str(uuid.uuid4()) + '_' + curr_time 78 | 79 | self.commit_test(grammar, unique_id) 80 | self.coverage.found(id) 81 | elif status == 0: 82 | self.coverage.record(id, grammar, self.coverage_paths[thread]) 83 | else: 84 | self.coverage.invalid(id) 85 | 86 | def validate(self, output): 87 | if output is 'Invalid': 88 | return -1 89 | if output is not None: 90 | pre = output.split(b'Begin')[0].replace(b'-'*51, b'').strip() 91 | pre = pre.split(b'tracing.\n')[1] 92 | pre = pre.split(b' ', 1)[1] 93 | post = output.split(b'Begin')[1].split(b'Turbofan\n')[2].strip() 94 | post = post.split(b' ', 1)[1] 95 | if pre != post: 96 | return 1 97 | return 0 98 | 99 | return 1 100 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/iterative.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import subprocess 4 | import uuid 5 | 6 | from datetime import datetime 7 | 8 | from coverage.iterative import recorder 9 | 10 | from .base import BaseFuzzer 11 | 12 | 13 | class IterativeFuzzer(BaseFuzzer): 14 | def __init__(self, threads, d8, crashes, tests, debug): 15 | self.logger = logging.getLogger(__name__) 16 | 17 | self.d8 = d8 18 | self.crashes = crashes 19 | self.tests = tests 20 | self.debug = debug 21 | 22 | coverage_dir = os.path.join('/dev/shm', 'vasilisk_coverage') 23 | if not os.path.exists(coverage_dir): 24 | self.logger.info('creating coverage dir') 25 | os.makedirs(coverage_dir) 26 | 27 | self.coverage_paths = [] 28 | for thread in range(threads): 29 | coverage_path = os.path.join( 30 | coverage_dir, 'thread-{}'.format(thread) 31 | ) 32 | self.coverage_paths.append(coverage_path) 33 | 34 | if not os.path.exists(coverage_path): 35 | self.logger.info('creating thread specific coverage dir') 36 | os.makedirs(coverage_path) 37 | 38 | self.coverage = recorder.CoverageRecorder() 39 | 40 | def execute(self, test_case, thread): 41 | options = ['-e', '--allow-natives-syntax', '--trace-turbo', 42 | '--trace-turbo-path', self.coverage_paths[thread]] 43 | 44 | try: 45 | return subprocess.check_output([self.d8] + options + [test_case]) 46 | except subprocess.CalledProcessError as e: 47 | self.logger.error(e) 48 | return None 49 | 50 | def fuzz(self, test_case, thread): 51 | unique_id = None 52 | grammar, test_case = test_case 53 | if self.debug: 54 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 55 | unique_id = str(uuid.uuid4()) + '_' + curr_time 56 | self.create_test(test_case, unique_id) 57 | 58 | output = self.execute(test_case, thread) 59 | 60 | if not self.validate(output): 61 | if unique_id is None: 62 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 63 | unique_id = str(uuid.uuid4()) + '_' + curr_time 64 | 65 | self.commit_test(test_case, unique_id) 66 | 67 | self.coverage.record(grammar, self.coverage_paths[thread]) 68 | 69 | def validate(self, output): 70 | if output is not None: 71 | return True 72 | return False 73 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/optimize.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import subprocess 3 | import uuid 4 | 5 | from datetime import datetime 6 | 7 | from .base import BaseFuzzer 8 | 9 | 10 | class OptimizeFuzzer(BaseFuzzer): 11 | def __init__(self, thread, d8, crashes, tests, debug): 12 | self.logger = logging.getLogger(__name__) 13 | 14 | self.d8 = d8 15 | self.crashes = crashes 16 | self.tests = tests 17 | self.debug = debug 18 | 19 | def execute(self, test_case): 20 | options = ['-e', '--allow-natives-syntax'] 21 | 22 | try: 23 | return subprocess.check_output([self.d8] + options + [test_case]) 24 | except subprocess.CalledProcessError as e: 25 | self.logger.error(e) 26 | return None 27 | 28 | def fuzz(self, test_case): 29 | unique_id = None 30 | 31 | if self.debug: 32 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 33 | unique_id = str(uuid.uuid4()) + '_' + curr_time 34 | self.create_test(test_case, unique_id) 35 | 36 | output = self.execute(test_case) 37 | 38 | if not self.validate(output): 39 | if unique_id is None: 40 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 41 | unique_id = str(uuid.uuid4()) + '_' + curr_time 42 | 43 | self.commit_test(test_case, unique_id) 44 | 45 | def validate(self, output): 46 | # values = output.split(b'optimized:\n') 47 | self.logger.debug(output) 48 | # return values[0] == values[1] 49 | return True 50 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/probablistic.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import subprocess 4 | import uuid 5 | 6 | from datetime import datetime 7 | 8 | from coverage.probabilistic import recorder 9 | 10 | from .base import BaseFuzzer 11 | 12 | 13 | class ProbablisticFuzzer(BaseFuzzer): 14 | def __init__(self, threads, d8, crashes, tests, debug): 15 | self.logger = logging.getLogger(__name__) 16 | 17 | self.d8 = d8 18 | self.crashes = crashes 19 | self.tests = tests 20 | self.debug = debug 21 | 22 | coverage_dir = os.path.join('/dev/shm', 'vasilisk_coverage') 23 | if not os.path.exists(coverage_dir): 24 | self.logger.info('creating coverage dir') 25 | os.makedirs(coverage_dir) 26 | 27 | self.coverage_paths = [] 28 | for thread in range(threads): 29 | coverage_path = os.path.join( 30 | coverage_dir, 'thread-{}'.format(thread) 31 | ) 32 | self.coverage_paths.append(coverage_path) 33 | 34 | if not os.path.exists(coverage_path): 35 | self.logger.info('creating thread specific coverage dir') 36 | os.makedirs(coverage_path) 37 | 38 | self.coverage = recorder.CoverageRecorder() 39 | 40 | def execute(self, test_case, thread): 41 | options = ['-e', '--allow-natives-syntax', '--trace-turbo', 42 | '--trace-turbo-path', self.coverage_paths[thread]] 43 | 44 | try: 45 | return subprocess.check_output([self.d8] + options + [test_case]) 46 | except subprocess.CalledProcessError as e: 47 | self.logger.error(e) 48 | return None 49 | 50 | def fuzz(self, test_case, thread): 51 | unique_id = None 52 | grammar, test_case = test_case 53 | 54 | if self.debug: 55 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 56 | unique_id = str(uuid.uuid4()) + '_' + curr_time 57 | self.create_test(test_case, unique_id) 58 | 59 | output = self.execute(test_case, thread) 60 | 61 | if not self.validate(output): 62 | if unique_id is None: 63 | curr_time = datetime.now().strftime('%Y.%m.%d-%H:%M:%S') 64 | unique_id = str(uuid.uuid4()) + '_' + curr_time 65 | 66 | self.commit_test(test_case, unique_id) 67 | 68 | self.coverage.record(grammar, self.coverage_paths[thread]) 69 | 70 | def validate(self, output): 71 | if output is not None: 72 | return True 73 | return False 74 | -------------------------------------------------------------------------------- /vasilisk/fuzzers/verify.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import subprocess 3 | 4 | from .base import BaseFuzzer 5 | 6 | 7 | class VerifyFuzzer(BaseFuzzer): 8 | def __init__(self, threads, d8, crashes, tests, debug): 9 | self.logger = logging.getLogger(__name__) 10 | 11 | self.d8 = d8 12 | 13 | def execute(self, test_case): 14 | options = ['-e', '--allow-natives-syntax'] 15 | 16 | try: 17 | return subprocess.check_output([self.d8] + options + [test_case]) 18 | except subprocess.CalledProcessError as e: 19 | self.logger.error(e) 20 | return None 21 | 22 | def fuzz(self, test_case, thread): 23 | grammar, test_case = test_case 24 | 25 | output = self.execute(test_case) 26 | 27 | if not self.validate(output): 28 | self.logger.info(f'invalid rule: {grammar[0]}') 29 | else: 30 | self.logger.info(f'valid rule: {grammar[0]}') 31 | self.logger.info(test_case) 32 | 33 | def validate(self, output): 34 | if output is not None: 35 | return True 36 | return False 37 | -------------------------------------------------------------------------------- /vasilisk/grammars/__init__.py: -------------------------------------------------------------------------------- 1 | from .optimize import OptimizeGrammar 2 | from .probabilistic import ProbabilisticGrammar 3 | from .iterative import IterativeGrammar 4 | from .verify import VerifyGrammar 5 | from .grammar import Grammar 6 | 7 | grammars = {'optimize': OptimizeGrammar, 8 | 'probabilistic': ProbabilisticGrammar, 9 | 'iterative': IterativeGrammar, 10 | 'verify': VerifyGrammar, 11 | 'groups': Grammar} 12 | -------------------------------------------------------------------------------- /vasilisk/grammars/base.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class BaseGrammar(ABC): 5 | def __init__(self): 6 | pass 7 | 8 | @abstractmethod 9 | def generate(self): 10 | """Generates Test Case From Grammar""" 11 | pass 12 | -------------------------------------------------------------------------------- /vasilisk/grammars/dharma_grammar.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import struct 4 | 5 | import dharma 6 | 7 | from .base import BaseGrammar 8 | 9 | 10 | class DharmaGrammar(BaseGrammar): 11 | def __init__(self, grammars): 12 | random.seed(struct.unpack('q', os.urandom(8))[0]) 13 | self.settings = open(os.path.join( 14 | os.path.dirname(os.path.abspath(dharma.__file__)), 15 | 'settings.py' 16 | ), 'r') 17 | 18 | self.create_dharma(grammars) 19 | 20 | def create_dharma(self, grammars): 21 | grammars = [open(grammar, 'r') for grammar in grammars] 22 | 23 | self.dharma = dharma.DharmaMachine() 24 | self.dharma.process_settings(self.settings) 25 | self.dharma.process_grammars(grammars) 26 | 27 | def generate(self): 28 | return self.dharma.generate_content() 29 | -------------------------------------------------------------------------------- /vasilisk/grammars/grammar.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import itertools 3 | import os 4 | import logging 5 | import random 6 | import re 7 | import time 8 | 9 | from collections import Counter 10 | 11 | from coverage.groups import handler 12 | 13 | from .base import BaseGrammar 14 | 15 | 16 | class Grammar(BaseGrammar): 17 | def __init__(self, repeat=4): 18 | self.logger = logging.getLogger(__name__) 19 | 20 | current_dir = os.path.dirname(os.path.realpath(__file__)) 21 | templates = os.path.join(current_dir, 'templates') 22 | 23 | dependencies = os.path.join(templates, 'dependencies') 24 | grammar_deps = [ 25 | os.path.join(dependencies, grammar) 26 | for grammar in os.listdir(os.path.join(dependencies)) 27 | ] 28 | 29 | actions = os.path.join(templates, 'actions.dg') 30 | controls = os.path.join(templates, 'controls.dg') 31 | variables = os.path.join(templates, 'variables.dg') 32 | 33 | grammars = grammar_deps + [actions, controls, variables] 34 | 35 | self.xref_re = r'''( 36 | (?P\+)(?P[a-zA-Z0-9:_]+)(?P=type)| 37 | %repeat%\(\s*(?P.+?)\s*(,\s*['"](?P.*?)['"])?\s*(,\s*(?Pnodups))?\s*\)| 38 | %range%\((?P.+?)-(?P.+?)\)| 39 | %choice%\(\s*(?P.+?)\s*\)| 40 | %unique%\(\s*(?P.+?)\s*\) 41 | )''' 42 | 43 | self.corpus = {} 44 | self.repeat_max = repeat 45 | self.repeat_depth = 2 46 | self.max_group_size = 10 47 | 48 | self.interactions = ['+', '-', '/', '*'] 49 | 50 | for grammar in grammars: 51 | grammar_name = os.path.basename(grammar).replace('.dg', '') 52 | self.corpus[grammar_name] = self.parse(grammar) 53 | 54 | self.unravel('actions') 55 | self.unravel('controls') 56 | self.unravel('variables') 57 | 58 | logging.info('FINISHED UNRAVELING') 59 | 60 | logging.debug('final actions:') 61 | logging.debug('\n'.join(self.corpus['actions']['regex'])) 62 | 63 | logging.debug('final controls:') 64 | logging.debug('\n'.join(self.corpus['controls']['LanguageConstructs'])) 65 | 66 | logging.debug('final variables:') 67 | logging.debug('\n'.join(self.corpus['variables']['regexptype'])) 68 | 69 | self.action_depth = 5 70 | self.action_size = 5 71 | self.control_depth = 1 72 | self.control_size = 1 73 | 74 | self.actions = {} 75 | self.controls = {} 76 | self.variables = {} 77 | 78 | self.grammar_cache = {} 79 | 80 | self.actions_pool = [] 81 | self.controls_pool = [] 82 | self.variables_pool = [] 83 | 84 | self.curr_action = None 85 | self.curr_control = None 86 | self.curr_variable = None 87 | 88 | self.mutate_set = [] 89 | 90 | self.load_pools() 91 | self.load() 92 | self.coverage = handler.CoverageHandler() 93 | 94 | self.wrapper = ('function f(){{ {} }} %DebugPrint(f());' 95 | '%OptimizeFunctionOnNextCall(f);%DebugPrint(f());') 96 | 97 | def parse(self, grammar): 98 | with open(grammar, 'r') as f: 99 | grammar_text = f.read() 100 | 101 | grammar_split = [rule.strip() for rule in grammar_text.split('\n\n')] 102 | rules = {} 103 | 104 | for rule in grammar_split: 105 | if ':=' not in rule: 106 | continue 107 | 108 | title, subrules = [r.strip() for r in rule.split(':=')] 109 | 110 | rules[title] = [] 111 | subrules = [subrule.strip() for subrule in subrules.split('\n')] 112 | for subrule in subrules: 113 | rules[title].append(subrule) 114 | 115 | return rules 116 | 117 | def xref(self, token): 118 | out = [] 119 | for m in re.finditer(self.xref_re, token, re.VERBOSE | re.DOTALL): 120 | if m.group('type') == '+': 121 | out.append((m.start('xref'), m.end('xref'))) 122 | return out 123 | 124 | def unresolved_xref(self, grammar, token): 125 | for match in re.finditer(r'''\+(?P[a-zA-Z0-9:_]+)\+''', token): 126 | if ':' not in match.group('xref'): 127 | rule_l = token[:match.start('xref')] 128 | rule_r = token[match.end('xref'):] 129 | token = rule_l + grammar + ':' + match.group('xref') + rule_r 130 | 131 | return token 132 | 133 | def parse_xrefs(self, grammar, subrule, common=False, history=None): 134 | self.logger.debug('process grammar: %s | %s', grammar, subrule) 135 | 136 | if history is None: 137 | history = [] 138 | 139 | xrefs = self.xref(subrule) 140 | new_subrules = [] 141 | 142 | self.logger.debug('history: %s', str(history)) 143 | 144 | if subrule in history: 145 | self.logger.debug('found in history: %s', str(subrule)) 146 | return [] 147 | 148 | if not xrefs: 149 | return [self.unresolved_xref(grammar, subrule)] 150 | 151 | expanded_rules = [] 152 | rule_parts = [] 153 | prev_end = 0 154 | for xref_indices in xrefs: 155 | rule_parts.append(subrule[prev_end:xref_indices[0] - 1]) 156 | rule_parts.append(0) 157 | 158 | xref = subrule[xref_indices[0]:xref_indices[1]] 159 | 160 | if ':' in xref: 161 | xref_grammar, xref_rule = xref.split(':') 162 | else: 163 | xref_grammar, xref_rule = grammar, xref 164 | 165 | xref_subrules = self.corpus[xref_grammar][xref_rule] 166 | self.logger.debug('xref_subrules: %s | %s', 167 | xref_rule, xref_subrules) 168 | 169 | if not common and xref_grammar == 'common': 170 | parsed_subrules = ['+' + xref + '+'] 171 | else: 172 | parsed_subrules = [] 173 | for xref_subrule in xref_subrules: 174 | parsed_subrules += self.parse_xrefs( 175 | xref_grammar, xref_subrule, common, history + [subrule] 176 | ) 177 | 178 | self.logger.debug('parsed_subrules: %s', parsed_subrules) 179 | 180 | expanded_rules.append(parsed_subrules) 181 | 182 | prev_end = xref_indices[1] + 1 183 | 184 | rule_parts.append(subrule[xref_indices[1] + 1:]) 185 | rule_fmt = '' 186 | for part in rule_parts: 187 | if part == 0: 188 | rule_fmt += '{}' 189 | else: 190 | if '{' in part: 191 | part = part.replace('{', '{{') 192 | 193 | if '}' in part: 194 | part = part.replace('}', '}}') 195 | 196 | rule_fmt += part 197 | 198 | self.logger.debug('expanded_rules: %s', expanded_rules) 199 | products = itertools.product(*expanded_rules) 200 | 201 | for product in products: 202 | new_rule = rule_fmt.format(*product) 203 | new_rule = self.unresolved_xref(grammar, new_rule) 204 | new_subrules.append(new_rule) 205 | 206 | self.logger.debug('result: %s | %s', grammar, new_subrules) 207 | return new_subrules 208 | 209 | def unravel(self, grammar): 210 | for rule, subrules in self.corpus[grammar].items(): 211 | cumulative_subrules = [] 212 | for subrule in subrules: 213 | new_subrules = self.parse_xrefs(grammar, subrule) 214 | 215 | if new_subrules: 216 | cumulative_subrules += new_subrules 217 | else: 218 | cumulative_subrules.append(subrule) 219 | 220 | self.corpus[grammar][rule] = cumulative_subrules 221 | 222 | def parse_func(self, grammar, rule, history=None): 223 | if history is None: 224 | history = {} 225 | 226 | m = re.search(self.xref_re, rule, re.VERBOSE | re.DOTALL) 227 | 228 | if not m: 229 | return rule 230 | 231 | if m.group('repeat') is not None: 232 | repeat, separator, nodups = m.group('repeat', 'separator', 233 | 'nodups') 234 | 235 | if separator is not None: 236 | end = m.end('separator') + 1 237 | elif nodups is not None: 238 | end = m.end('nodups') 239 | else: 240 | end = m.end('repeat') 241 | 242 | if separator is None: 243 | separator = '' 244 | 245 | xrefs = self.parse_xrefs(grammar, repeat, True) 246 | out = [] 247 | repeat_power = random.randint(1, self.repeat_max) 248 | if repeat not in history: 249 | history[repeat] = 0 250 | history[repeat] += 1 251 | 252 | no_repeats = [] 253 | for no_repeat, count in history.items(): 254 | if count >= self.repeat_depth: 255 | no_repeats.append(no_repeat) 256 | 257 | search_space = len(xrefs) 258 | for i in range(repeat_power): 259 | xref = random.choice(xrefs) 260 | 261 | invalid = True 262 | count = 0 263 | while invalid: 264 | if count > search_space: 265 | break 266 | 267 | invalid = False 268 | for no_repeat in no_repeats: 269 | if no_repeat in xref: 270 | invalid = True 271 | xref = random.choice(xrefs) 272 | count += 1 273 | break 274 | 275 | out.append(xref) 276 | 277 | result = separator.join(out) 278 | 279 | rule_l = rule[:m.start('repeat') - 1 - len('%repeat%')] 280 | rule_r = rule[end + 1:] 281 | result = rule_l + result + rule_r 282 | 283 | return self.parse_func(grammar, result, history) 284 | 285 | if m.group('unique') is not None: 286 | unique = m.group('unique') 287 | xrefs = self.parse_xrefs(grammar, unique, True) 288 | size = random.randint(1, len(xrefs)) 289 | possible = list(itertools.combinations(xrefs, r=size)) 290 | rule_l = rule[:m.start('unique') - 1].replace('%unique%', '') 291 | rule_r = rule[m.end('unique') + 1:] 292 | result = rule_l + ''.join(random.choice(possible)) + rule_r 293 | 294 | return self.parse_func(grammar, result, history) 295 | 296 | if m.group('start') is not None and m.group('end') is not None: 297 | b_range = m.group('start') 298 | e_range = m.group('end') 299 | result = '' 300 | 301 | if b_range.isalpha(): 302 | result = chr(random.randint(ord(b_range), ord(e_range))) 303 | else: 304 | result = str(random.randint(int(b_range), int(e_range))) 305 | 306 | rule_l = rule[:rule.index('%range%')] 307 | rule_r = rule[rule.index('%range%'):] 308 | rule_r = rule_r[rule_r.index(')') + 1:] 309 | result = rule_l + result + rule_r 310 | 311 | return self.parse_func(grammar, result, history) 312 | 313 | if m.group('type') == '+': 314 | xref = rule[m.start('xref') - 1:m.end('xref') + 1] 315 | if 'common' in xref: 316 | expanded = random.choice( 317 | self.parse_xrefs(grammar, xref, True) 318 | ) 319 | 320 | rule_l = rule[:m.start('xref') - 1] 321 | rule_r = rule[m.end('xref') + 1:] 322 | result = rule_l + expanded + rule_r 323 | 324 | return self.parse_func(grammar, result, history) 325 | 326 | def load_cache(self, grammar, rules): 327 | ''' 328 | loads a list of grammars and checks regex to output code 329 | ''' 330 | logging.debug('loading %s:%s into cache', grammar, rules) 331 | self.grammar_cache[grammar] = {} 332 | 333 | for rule in rules: 334 | rule_name, index = rule.split(':') 335 | subrule = self.corpus[grammar][rule_name][int(index)] 336 | 337 | self.grammar_cache[grammar][rule] = self.parse_func(grammar, 338 | subrule) 339 | 340 | def load_pools(self): 341 | for rule, subrules in self.corpus['actions'].items(): 342 | for i, subrule in enumerate(subrules): 343 | self.actions[f'{rule}:{i}'] = subrule 344 | for rule, subrules in self.corpus['controls'].items(): 345 | for i, subrule in enumerate(subrules): 346 | self.controls[f'{rule}:{i}'] = subrule 347 | 348 | def find_variables(self, actions): 349 | variable_count = Counter() 350 | for action in actions: 351 | rule, index = action.split(':') 352 | token = self.corpus['actions'][rule][int(index)] 353 | variable_regex = r'''\!(?P[a-zA-Z0-9:_]+)\!''' 354 | 355 | for match in re.finditer(variable_regex, token): 356 | variable_count[match.group('xref')] += 1 357 | 358 | return variable_count 359 | 360 | def load_variables(self, actions): 361 | variable_count = self.find_variables(actions) 362 | 363 | variables = [] 364 | for variable, count in variable_count.items(): 365 | self.logger.debug('Variable %s with count %s', variable, count) 366 | pool = self.corpus['variables'][variable] 367 | count = min(count, len(pool)) 368 | count = random.randint(1, count) 369 | selections = random.sample(range(len(pool)), count) 370 | for selection in selections: 371 | variables.append(variable + ':' + str(selection)) 372 | 373 | return variables 374 | 375 | def load(self): 376 | self.actions_pool = random.sample(self.actions.keys(), 377 | self.action_size) 378 | self.controls_pool = random.sample(self.controls.keys(), 379 | self.control_size) 380 | self.variables_pool = self.load_variables(self.actions_pool) 381 | 382 | self.variables = {} 383 | for variable in self.variables_pool: 384 | name, _ = variable.split(':') 385 | if name not in self.variables: 386 | self.variables[name] = [] 387 | self.variables[name].append(variable) 388 | 389 | self.load_cache('actions', self.actions_pool) 390 | self.load_cache('controls', self.controls_pool) 391 | self.load_cache('variables', self.variables_pool) 392 | 393 | self.curr_actions = self.iterate_rules(self.action_depth, 394 | self.action_size) 395 | self.curr_controls = self.iterate_rules(self.control_depth, 396 | self.control_size) 397 | 398 | self.curr_action = next(self.curr_actions) 399 | self.curr_control = next(self.curr_controls) 400 | self.curr_variable = self.iterate_variables() 401 | 402 | def iterate_rules(self, depth, size): 403 | rules = [0] 404 | 405 | while len(rules) <= depth: 406 | yield rules 407 | rules[0] += 1 408 | for i in range(len(rules) - 1): 409 | if rules[i] >= size: 410 | rules[i] = 0 411 | rules[i + 1] += 1 412 | 413 | if rules[-1] >= size: 414 | rules = [0 for _ in range(len(rules) + 1)] 415 | 416 | yield None 417 | 418 | def iterate_variables(self): 419 | if self.curr_action is None: 420 | return None 421 | 422 | actions = [self.actions_pool[i] for i in self.curr_action] 423 | variable_count = self.find_variables(actions) 424 | 425 | result = [] 426 | for variable, count in variable_count.items(): 427 | count = random.randint(1, count) 428 | for _ in range(count): 429 | result.append(random.choice(self.variables[variable])) 430 | 431 | return result 432 | 433 | def mutate(self, group): 434 | mutations = [self.mutate_actions, self.mutate_variables, 435 | self.mutate_interactions] 436 | mutation = random.choice(mutations) 437 | return mutation(group) 438 | 439 | def mutate_interactions(self, group): 440 | interactions = group.get_interactions() 441 | if not interactions: 442 | return group 443 | elif len(interactions) == 1: 444 | rand_idx = 0 445 | else: 446 | rand_idx = random.randint(0, len(interactions) - 1) 447 | interactions[rand_idx] = random.choice(self.interactions) 448 | group.set_interactions(interactions) 449 | return group 450 | 451 | def mutate_actions(self, group): 452 | actions = group.get_actions() 453 | mutate_action = random.choice(list(actions.keys())) 454 | corresponding_var = actions[mutate_action] 455 | action_type, _ = mutate_action.split(':') 456 | num_choices = len(self.corpus['actions'][action_type]) 457 | new_action = str(random.randint(0, num_choices - 1)) 458 | del actions[mutate_action] 459 | actions[':'.join((action_type, new_action))] = corresponding_var 460 | group.set_actions(actions) 461 | return group 462 | 463 | def mutate_variables(self, group): 464 | variables = group.get_variables() 465 | mutate = random.choice(list(variables.keys())) 466 | variable_type, _ = variables[mutate].split(':') 467 | num_choices = len(self.corpus['variables'][variable_type]) 468 | new_variable = str(random.randint(0, num_choices - 1)) 469 | variables[mutate] = ':'.join((variable_type, new_variable)) 470 | group.set_variables(variables) 471 | return group 472 | 473 | def get_var_type(self, action): 474 | variable_regex = r'''\!(?P[a-zA-Z0-9:_]+)\!''' 475 | m = re.search(variable_regex, action) 476 | if not m: 477 | return None 478 | self.logger.debug(action, action) 479 | return m.group('xref') 480 | 481 | def build_group(self, group): 482 | actions, variables, controls, interactions = group.unpack() 483 | lines = [] 484 | 485 | for name, variable in variables.items(): 486 | lines.append(f'var {name}={variable}') 487 | 488 | for action, var in actions.items(): 489 | rule_name, index = action.split(':') 490 | subrule = self.corpus['actions'][rule_name][int(index)] 491 | action_template = self.parse_func('actions', subrule) 492 | var_type = self.get_var_type(action_template) 493 | lines.append(action_template.replace(f'!{var_type}!', var)) 494 | 495 | equation = '{}'.join(variables.keys()).format(*interactions) 496 | lines.append('var result=' + equation) 497 | 498 | controls_fmt = [] 499 | for control in controls: 500 | controls_fmt.append(control.replace('#actions#', '{}')) 501 | 502 | control_wrapper = '{}' 503 | for control in controls_fmt: 504 | control_wrapper = control_wrapper.format(control) 505 | 506 | control_wrapper = control_wrapper.format(';'.join(lines)) 507 | 508 | result = self.wrapper.format(control_wrapper) 509 | return f"'{result}'" 510 | 511 | def generate(self): 512 | if self.mutate_set: 513 | id = len(self.mutate_set) 514 | group = self.mutate(self.mutate_set.pop()) 515 | self.coverage.store_group(group) 516 | return (id, True, self.build_group(group)) 517 | # Generate new variables everytime we iterate actions 518 | # Run out of actions, do it again with next control 519 | # Run out of controls, reload 520 | if self.curr_action is None: 521 | self.curr_actions = self.iterate_rules(self.action_depth, 522 | self.action_size) 523 | self.curr_action = next(self.curr_actions) 524 | self.curr_variable = self.iterate_variables() 525 | self.curr_control = next(self.curr_controls) 526 | if self.curr_control is None: 527 | self.logger.info('Finish Generation') 528 | while not self.coverage.up_to_date(): 529 | self.logger.info(self.coverage.redis.get('processed')) 530 | self.logger.info(self.coverage.redis.get('generated')) 531 | time.sleep(0.5) 532 | self.logger.info('New Set') 533 | self.load() 534 | self.logger.info('Loaded New Set') 535 | self.coverage.reset() 536 | self.logger.info('Reset Coverage') 537 | if self.coverage.get_num_interesting() >= 400: 538 | logging.info('Start Mutation') 539 | self.mutate_set = self.coverage.get_most_interesting() * 5 540 | 541 | actions = [self.actions_pool[i] for i in self.curr_action] 542 | controls = [self.grammar_cache['controls'][self.controls_pool[i]] 543 | for i in self.curr_control] 544 | 545 | lines = [] 546 | assigned_variables = {} 547 | resolved_variables = {} 548 | variable_list = [] 549 | for i, variable in enumerate(self.curr_variable): 550 | rule = variable.split(':')[0] 551 | if rule not in assigned_variables: 552 | assigned_variables[rule] = [] 553 | curr_var = f'var{i}' 554 | 555 | assigned_variables[rule].append(curr_var) 556 | variable_list.append(curr_var) 557 | resolved = self.grammar_cache['variables'][variable] 558 | resolved_variables[curr_var] = variable 559 | lines.append(f'var {curr_var}={resolved}') 560 | 561 | random.shuffle(actions) 562 | assigned_variables_copy = copy.deepcopy(assigned_variables) 563 | actions_to_variables = {} 564 | for action in actions: 565 | resolved = self.grammar_cache['actions'][action] 566 | var_type = self.get_var_type(resolved) 567 | if not var_type: 568 | continue 569 | if assigned_variables[var_type]: 570 | var_choice = assigned_variables[var_type].pop() 571 | else: 572 | var_choice = random.choice(assigned_variables_copy[rule]) 573 | 574 | actions_to_variables[action] = var_choice 575 | lines.append(resolved.replace(f'!{var_type}!', var_choice)) 576 | 577 | equation = '{}'.join(variable_list) 578 | interactions = [] 579 | for _ in range(len(variable_list) - 1): 580 | interactions.append(random.choice(self.interactions)) 581 | equation = equation.format(*interactions) 582 | lines.append('var result=' + equation) 583 | 584 | controls_fmt = [] 585 | for control in controls: 586 | controls_fmt.append(control.replace('#actions#', '{}')) 587 | 588 | control_wrapper = '{}' 589 | for control in controls_fmt: 590 | control_wrapper = control_wrapper.format(control) 591 | 592 | control_wrapper = control_wrapper.format(';'.join(lines)) 593 | 594 | result = self.wrapper.format(control_wrapper) 595 | result = "'" + result + "'" 596 | 597 | id = ';'.join([':'.join(map(str, self.curr_action)), 598 | ':'.join(map(str, self.curr_control))]) 599 | final = len(self.curr_action) == self.action_depth 600 | self.coverage.store(id, actions_to_variables, resolved_variables, 601 | controls, interactions, final) 602 | 603 | self.curr_action = next(self.curr_actions) 604 | self.curr_variable = self.iterate_variables() 605 | 606 | return (id, final, result) 607 | 608 | 609 | if __name__ == '__main__': 610 | logging.basicConfig(level=logging.INFO) 611 | 612 | grammar = Grammar() 613 | start_time = time.time() 614 | for _ in range(100000): 615 | print(grammar.generate()) 616 | 617 | print('took :{} seconds'.format(time.time() - start_time)) 618 | -------------------------------------------------------------------------------- /vasilisk/grammars/iterative.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import random 4 | import time 5 | 6 | from coverage.iterative import handler 7 | 8 | from .dharma_grammar import DharmaGrammar 9 | 10 | 11 | class IterativeGrammar(DharmaGrammar): 12 | def __init__(self): 13 | self.logger = logging.getLogger(__name__) 14 | 15 | grammar_dir = os.path.join('/dev/shm', 'vasilisk_grammar') 16 | if not os.path.exists(grammar_dir): 17 | self.logger.info('creating coverage dir') 18 | os.makedirs(grammar_dir) 19 | 20 | self.grammar_path = os.path.join(grammar_dir, 'gen_grammar.dg') 21 | with open(self.grammar_path, 'w+'): 22 | pass 23 | 24 | current_dir = os.path.dirname(os.path.realpath(__file__)) 25 | templates = os.path.join(current_dir, 'templates') 26 | 27 | with open(os.path.join(templates, 'actions.dg'), 'r') as f: 28 | self.all_actions = f.read() 29 | 30 | dependencies = os.path.join(templates, 'dependencies') 31 | self.grammar_deps = [ 32 | os.path.join(dependencies, grammar) 33 | for grammar in os.listdir(os.path.join(dependencies)) 34 | ] 35 | 36 | self.actions = self.parse(os.path.join(templates, 'actions.dg')) 37 | self.controls = self.parse(os.path.join(templates, 'controls.dg')) 38 | 39 | self.coverage = handler.CoverageHandler() 40 | 41 | self.action_depth = 5 42 | self.control_depth = 1 43 | 44 | self.action_size = 5 45 | self.control_size = 1 46 | 47 | self.saved_req = 100 48 | 49 | self.curr_combs = 0 50 | 51 | self.curr_actions = self.get_actions() 52 | 53 | self.actions_pool = [] 54 | self.controls_pool = [] 55 | 56 | self.grammars = self.grammar_deps + [self.grammar_path] 57 | super().__init__(self.grammars) 58 | 59 | def parse(self, grammar_path): 60 | with open(grammar_path, 'r') as f: 61 | grammar_text = f.read() 62 | 63 | grammar_split = [rule.strip() for rule in grammar_text.split('\n\n')] 64 | rules = {} 65 | 66 | for rule in grammar_split: 67 | title, subrules = [r.strip() for r in rule.split(':=')] 68 | 69 | subrules = [subrule.strip() for subrule in subrules.split('\n')] 70 | for i, subrule in enumerate(subrules): 71 | rules[title + ':' + str(i)] = subrule 72 | 73 | return rules 74 | 75 | def load_rules(self): 76 | while True: 77 | self.actions_pool = random.sample(self.actions.keys(), 78 | self.action_size) 79 | self.controls_pool = random.sample(self.controls.keys(), 80 | self.control_size) 81 | 82 | if self.coverage.unique(self.actions_pool, self.controls_pool): 83 | break 84 | 85 | def get_actions(self): 86 | self.load_rules() 87 | actions = [0] 88 | 89 | while len(actions) <= self.action_depth: 90 | yield actions 91 | actions[0] += 1 92 | for i in range(len(actions) - 1): 93 | if actions[i] >= self.action_size: 94 | actions[i] = 0 95 | actions[i + 1] += 1 96 | self.curr_combs += 1 97 | 98 | if actions[-1] >= self.action_size: 99 | actions = [0 for _ in range(len(actions) + 1)] 100 | 101 | yield None 102 | 103 | def generate(self): 104 | actions = next(self.curr_actions) 105 | if actions is None: 106 | while self.coverage.get_count() < self.curr_combs: 107 | time.sleep(0.5) 108 | 109 | self.coverage.score(self.actions_pool, self.controls_pool, 110 | self.action_depth, self.control_depth) 111 | self.coverage.reset(self.actions_pool, self.controls_pool) 112 | self.curr_combs = 0 113 | 114 | # if self.coverage.get_saved() > self.saved_req: 115 | 116 | self.curr_actions = self.get_actions() 117 | actions = next(self.curr_actions) 118 | 119 | headers = [ 120 | '%%% Generated Grammar', 121 | '%const% VARIANCE_MAX := 1', 122 | '%const% VARIANCE_TEMPLATE := "function f(){%s} %%DebugPrint(f());' 123 | '%%OptimizeFunctionOnNextCall(f); %%DebugPrint(f());"', 124 | '%const% MAX_REPEAT_POWER := 4' 125 | ] 126 | 127 | with open(self.grammar_path, 'w') as f: 128 | for header in headers: 129 | f.write(header + '\n') 130 | 131 | f.write('\n') 132 | 133 | actions = [self.actions_pool[i] for i in actions] 134 | 135 | with open(self.grammar_path, 'a') as f: 136 | f.write('%section% := value\n\n') 137 | f.write(self.all_actions + '\n') 138 | for i, action in enumerate(actions): 139 | f.write(f'action{i} :=\n\t{self.actions[action]}\n\n') 140 | 141 | f.write('value :=\n\t') 142 | 143 | for i in range(len(actions)): 144 | f.write(f'+action{i}+;') 145 | 146 | f.write('\n\n') 147 | 148 | control = list(self.controls.keys())[0] 149 | 150 | with open(self.grammar_path, 'a') as f: 151 | f.write('%section% := variance\n\n') 152 | f.write(f'variance :=\n\t{self.controls[control]}\n\n') 153 | 154 | self.create_dharma(self.grammars) 155 | 156 | return ((actions, [control]), super().generate()) 157 | -------------------------------------------------------------------------------- /vasilisk/grammars/optimize.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | 4 | from .dharma_grammar import DharmaGrammar 5 | 6 | 7 | class OptimizeGrammar(DharmaGrammar): 8 | def __init__(self): 9 | self.logger = logging.getLogger(__name__) 10 | 11 | grammar_path = os.path.join( 12 | os.path.dirname(os.path.abspath(__file__)), 13 | '..', 'grammars', 'templates' 14 | ) 15 | 16 | grammars = ['grammar.dg', 'semantics.dg'] 17 | super().__init__([os.path.join(grammar_path, g) for g in grammars]) 18 | -------------------------------------------------------------------------------- /vasilisk/grammars/probabilistic.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import random 4 | 5 | from coverage.probabilistic import handler 6 | 7 | from .dharma_grammar import DharmaGrammar 8 | 9 | 10 | class ProbabilisticGrammar(DharmaGrammar): 11 | def __init__(self): 12 | self.logger = logging.getLogger(__name__) 13 | 14 | grammar_dir = os.path.join('/dev/shm', 'vasilisk_grammar') 15 | if not os.path.exists(grammar_dir): 16 | self.logger.info('creating coverage dir') 17 | os.makedirs(grammar_dir) 18 | 19 | self.grammar_path = os.path.join(grammar_dir, 'gen_grammar.dg') 20 | with open(self.grammar_path, 'w+'): 21 | pass 22 | 23 | current_dir = os.path.dirname(os.path.realpath(__file__)) 24 | templates = os.path.join(current_dir, 'templates') 25 | 26 | with open(os.path.join(templates, 'values.dg'), 'r') as f: 27 | self.all_values = f.read() 28 | 29 | self.values = self.parse(os.path.join(templates, 'values.dg')) 30 | self.controls = self.parse(os.path.join(templates, 'controls.dg')) 31 | 32 | self.coverage = handler.CoverageHandler(self.values, self.controls) 33 | 34 | self.grammars = [self.grammar_path] 35 | super().__init__(self.grammars) 36 | 37 | def parse(self, grammar_path): 38 | with open(grammar_path, 'r') as f: 39 | grammar_text = f.read() 40 | 41 | grammar_split = [rule.strip() for rule in grammar_text.split('\n\n')] 42 | rules = {} 43 | 44 | for rule in grammar_split: 45 | title, subrules = [r.strip() for r in rule.split(':=')] 46 | 47 | subrules = [subrule.strip() for subrule in subrules.split('\n')] 48 | for i, subrule in enumerate(subrules): 49 | rules[title + ':' + str(i)] = subrule 50 | 51 | return rules 52 | 53 | def load_probabilities(self): 54 | self.values_probability = self.coverage.get_values() 55 | self.controls_probability = self.coverage.get_controls() 56 | 57 | def choice(self, probabilities): 58 | choice = random.randint(0, sum(probabilities.values())) 59 | 60 | curr = 0 61 | for rule, probability in probabilities.items(): 62 | curr += probability 63 | if curr >= choice: 64 | return rule 65 | 66 | def generate(self): 67 | self.load_probabilities() 68 | 69 | headers = [ 70 | '%%% Generated Grammar', 71 | '%const% VARIANCE_MAX := 1', 72 | '%const% VARIANCE_TEMPLATE := "function f(){%s} %%DebugPrint(f());' 73 | '%%OptimizeFunctionOnNextCall(f); %%DebugPrint(f());"', 74 | '%const% MAX_REPEAT_POWER := 4' 75 | ] 76 | 77 | with open(self.grammar_path, 'w') as f: 78 | for header in headers: 79 | f.write(header + '\n') 80 | 81 | f.write('\n') 82 | 83 | value = self.choice(self.values_probability) 84 | 85 | with open(self.grammar_path, 'a') as f: 86 | f.write('%section% := value\n\n') 87 | f.write(self.all_values) 88 | f.write(f'\nvalue :=\n\t{self.values[value]}\n\n') 89 | 90 | control = self.choice(self.controls_probability) 91 | 92 | with open(self.grammar_path, 'a') as f: 93 | f.write('%section% := variance\n\n') 94 | f.write(f'variance :=\n\t{self.controls[control]}\n\n') 95 | 96 | self.create_dharma(self.grammars) 97 | 98 | return ((value, control), super().generate()) 99 | -------------------------------------------------------------------------------- /vasilisk/grammars/settings.py: -------------------------------------------------------------------------------- 1 | # pylint: disable = undefined-variable 2 | DharmaConst.VARIANCE_MIN = 1 3 | DharmaConst.VARIANCE_MAX = 8 4 | DharmaConst.VARIABLE_MIN = 1 5 | DharmaConst.VARIABLE_MAX = 4 6 | DharmaConst.VARIANCE_TEMPLATE = "%s" 7 | DharmaConst.MAX_REPEAT_POWER = 12 8 | DharmaConst.LEAF_TRIGGER = 256 9 | DharmaConst.URI_TABLE = { 10 | "images": "fuzzdata/samples/jpg/", 11 | "videos": "fuzzdata/samples/mp4/", 12 | "audios": "fuzzdata/samples/mp3/", 13 | } 14 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/actions.dg: -------------------------------------------------------------------------------- 1 | regex := 2 | !regexptype!.flags = "+regexp:flags+" 3 | !regexptype!.global = +common:bool+ 4 | !regexptype!.ignoreCase = +common:bool+ 5 | !regexptype!.multiline = +common:bool+ 6 | !regexptype!.sticky = +common:bool+ 7 | !regexptype!.unicode = +common:bool+ 8 | !regexptype!.exec("+common:text+") 9 | !regexptype!.test("+common:text+") 10 | !regexptype!.toString() 11 | !regexptype!.lastIndex 12 | !regexptype!.compile() 13 | "+common:text+".split(!regexptype!) 14 | "+common:text+".split(!regexptype!, +common:int+) 15 | 16 | array := 17 | !arrtype![+common:int+] 18 | !arrtype![+common:decimal_number+] 19 | delete !arrtype![+common:byte_int+] 20 | !arrtype!.length 21 | !arrtype!.length = +value:valtype+ 22 | !arrtype!.copyWithin(+common:int+) 23 | !arrtype!.copyWithin(+common:int+, +common:int+) 24 | !arrtype!.copyWithin(+common:int+, +common:int+, +common:int+) 25 | !arrtype!.fill(+value:valtype+) 26 | !arrtype!.fill(+value:valtype+, +common:int+) 27 | !arrtype!.fill(+value:valtype+, +common:int+, +common:int+) 28 | !arrtype!.pop() 29 | !arrtype!.push(+value:valtype+) 30 | !arrtype!.reverse() 31 | !arrtype!.shift() 32 | !arrtype!.splice(+common:int+, +common:int+, %repeat%(+value:valtype+, ", ")) 33 | !arrtype!.unshift(%repeat%(+value:valtype+, ", ")) 34 | !arrtype!.includes(+value:valtype+) 35 | !arrtype!.indexOf(+value:valtype+) 36 | !arrtype!.join() 37 | !arrtype!.join(+value:valtype+) 38 | !arrtype!.lastIndexOf(+value:valtype+) 39 | !arrtype!.entries() 40 | !arrtype!.slice() 41 | !arrtype!.slice(+common:int+) 42 | !arrtype!.slice(+common:int+, +common:int+) 43 | !arrtype!.toString() 44 | !arrtype!.toLocaleString() 45 | !arrtype!.keys() 46 | !arrtype!.values() 47 | !arrtype![+common:int+ % +array:any_arr+.length] 48 | !arrtype![+common:int+ % +array:any_arr+.length] = +value:valtype+ 49 | !arrtype![+common:int+] = +value:valtype+ 50 | !arrtype![+common:decimal_number+] = +value:valtype+ 51 | 52 | boolean := 53 | !bool!.toString() 54 | !bool!.valueOf() 55 | 56 | buffer := 57 | ArrayBuffer.isView(!arraybuffertype!) 58 | ArrayBuffer.transfer(!arraybuffertype!) 59 | ArrayBuffer.transfer(!arraybuffertype!, +common:int+) 60 | !arraybuffertype!.slice(+common:positive_integer+) 61 | !arraybuffertype!.slice(+common:positive_integer+, +common:positive_integer+) 62 | !typedarraytype!.buffer 63 | !typedarraytype!.byteLength 64 | !typedarraytype!.byteOffset 65 | !typedarraytype!.length 66 | !typedarraytype!.copyWithin(+common:positive_integer+, +common:positive_integer+) 67 | !typedarraytype!.copyWithin(+common:positive_integer+, +common:positive_integer+, +common:positive_integer+) 68 | !typedarraytype!.entries() 69 | !typedarraytype!.fill(+value:valtype+) 70 | !typedarraytype!.includes(+value:valtype+) 71 | !typedarraytype!.includes(+value:valtype+, +common:positive_integer+) 72 | !typedarraytype!.indexOf(+value:valtype+) 73 | !typedarraytype!.indexOf(+value:valtype+, +common:positive_integer+) 74 | !typedarraytype!.join() 75 | !typedarraytype!.join(+value:valtype+) 76 | !typedarraytype!.keys() 77 | !typedarraytype!.lastIndexOf(+value:valtype+) 78 | !typedarraytype!.lastIndexOf(+value:valtype+, +common:positive_integer+) 79 | !typedarraytype!.reverse() 80 | !typedarraytype!.set(+value:valtype+) 81 | !typedarraytype!.set(+value:valtype+, +common:positive_integer+) 82 | !typedarraytype!.slice() 83 | !typedarraytype!.slice(+common:integer+) 84 | !typedarraytype!.slice(+common:integer+, +common:integer+) 85 | !typedarraytype!.subarray() 86 | !typedarraytype!.subarray(+common:integer+, +common:integer+) 87 | !typedarraytype!.values() 88 | !typedarraytype!.toLocaleString() 89 | !typedarraytype!.toString() 90 | !typedarraytype![Symbol.iterator]() 91 | 92 | dataview := 93 | !dataviewtype!.buffer 94 | !dataviewtype!.buffer = +dataview:dataviewbuffer+ 95 | !dataviewtype!.byteLength 96 | !dataviewtype!.byteLength = +common:int+ 97 | !dataviewtype!.byteOffset 98 | !dataviewtype!.byteOffset = +common:int+ 99 | !dataviewtype!.getInt8(+dataview:get_args+) 100 | !dataviewtype!.getUInt8(+dataview:get_args+) 101 | !dataviewtype!.getInt16(+dataview:get_args+) 102 | !dataviewtype!.getUInt16(+dataview:get_args+) 103 | !dataviewtype!.getInt32(+dataview:get_args+) 104 | !dataviewtype!.getUInt32(+dataview:get_args+) 105 | !dataviewtype!.getFloat32(+dataview:get_args+) 106 | !dataviewtype!.getFloat64(+dataview:get_args+) 107 | !dataviewtype!.setInt8(+dataview:set_args+) 108 | !dataviewtype!.setUInt8(+dataview:set_args+) 109 | !dataviewtype!.setInt16(+dataview:set_args+) 110 | !dataviewtype!.setUInt16(+dataview:set_args+) 111 | !dataviewtype!.setInt32(+dataview:set_args+) 112 | !dataviewtype!.setUInt32(+dataview:set_args+) 113 | !dataviewtype!.setFloat32(+dataview:set_args+) 114 | !dataviewtype!.setFloat64(+dataview:set_args+) 115 | 116 | date := 117 | Date.now() 118 | !datetype!.getDate() 119 | !datetype!.getDay() 120 | !datetype!.dateFullYear() 121 | !datetype!.getHours() 122 | !datetype!.getMilliseconds() 123 | !datetype!.getMinutes() 124 | !datetype!.getMonth() 125 | !datetype!.getSeconds() 126 | !datetype!.getTime() 127 | !datetype!.getTimezoneOffset() 128 | !datetype!.getUTCDate() 129 | !datetype!.getUTCDay() 130 | !datetype!.getUTCFullYear() 131 | !datetype!.getUTCHours() 132 | !datetype!.getUTCMilliseconds() 133 | !datetype!.getUTCMinutes() 134 | !datetype!.getUTCMonth() 135 | !datetype!.getUTCSeconds() 136 | !datetype!.getYear() 137 | !datetype!.setDate(+common:int+) 138 | !datetype!.setFullYear(+common:int+) 139 | !datetype!.setHours(+common:int+) 140 | !datetype!.setMilliseconds(+common:int+) 141 | !datetype!.setMinutes(+common:int+) 142 | !datetype!.setMonth(+common:int+) 143 | !datetype!.setSeconds(+common:int+) 144 | !datetype!.setTime(+common:int+) 145 | !datetype!.setUTCDate(+common:int+) 146 | !datetype!.setUTCFullYear(+common:int+) 147 | !datetype!.setUTCHours(+common:int+) 148 | !datetype!.setUTCMilliseconds(+common:int+) 149 | !datetype!.setUTCMinutes(+common:int+) 150 | !datetype!.setUTCMonth(+common:int+) 151 | !datetype!.setUTCSeconds(+common:int+) 152 | !datetype!.setYear(+common:int+) 153 | !datetype!.toDateSTring() 154 | !datetype!.toISOString() 155 | !datetype!.toJSON() 156 | !datetype!.toGMTString() 157 | !datetype!.toLocaleDateString() 158 | !datetype!.toLocaleString() 159 | !datetype!.toLocaleTimeString() 160 | !datetype!.toString() 161 | !datetype!.toTimeString() 162 | !datetype!.toUTCString() 163 | !datetype!.valueOf() 164 | 165 | obj := 166 | !obj![+common:decimal_number+] = +value:valtype+ 167 | 168 | map := 169 | !maptype!.size 170 | !maptype!.clear() 171 | !maptype!.delete(+value:valtype+) 172 | !maptype!.entries() 173 | !maptype!.get(+value:valtype+) 174 | !maptype!.has(+value:valtype+) 175 | !maptype!.keys() 176 | !maptype!.set(+value:valtype+, +value:valtype+) 177 | !maptype!.values() 178 | !maptype![Symbol.iterator]() 179 | 180 | number := 181 | Number.isNaN(+value:valtype+) 182 | Number.isFinite(+value:valtype+) 183 | Number.isInteger(+value:valtype+) 184 | Number.isSafeInteger(+value:valtype+) 185 | Number.parseFloat(+value:valtype+) 186 | Number.parseInt(+value:valtype+) 187 | !numbertype!.toExponential() 188 | !numbertype!.toExponential(+common:byte_int+) 189 | !numbertype!.toFixed() 190 | !numbertype!.toFixed(+common:byte_int+) 191 | !numbertype!.toLocaleString() 192 | !numbertype!.toPrecision() 193 | !numbertype!.toPrecision(+common:byte_int+) 194 | !numbertype!.toString() 195 | !numbertype!.toString(+common:byte_int+) 196 | !numbertype!.toString(%range%(0-36)) 197 | !numbertype!.valueOf() 198 | 199 | set := 200 | !settype!.size 201 | !settype!.add(+value:valtype+) 202 | !settype!.clear() 203 | !settype!.delete(+value:valtype+) 204 | !settype!.entries() 205 | !settype!.has(+value:valtype+) 206 | !settype!.keys() 207 | !settype!.values() 208 | !settype![Symbol.iterator]() 209 | 210 | string := 211 | String.fromCharCode(%repeat%(+common:short_int+, ", ")) 212 | String.fromCodePoint(%repeat%(+common:int+, ", ")) 213 | !stringtype!.charAt(+common:int+) 214 | !stringtype!.charAt(+common:byte_int+) 215 | !stringtype!.charCodeAt(+common:int+) 216 | !stringtype!.charCodeAt(+common:byte_int+) 217 | !stringtype!.codePointAt(+common:int+) 218 | !stringtype!.codePointAt(+common:byte_int+) 219 | !stringtype!.concat(+string:stringtype+) 220 | !stringtype!.includes(+string:stringtype+) 221 | !stringtype!.endsWith(+string:stringtype+) 222 | !stringtype!.indexOf(+string:stringtype+) 223 | !stringtype!.indexOf(+string:stringtype+, +common:int+) 224 | !stringtype!.lastIndexOf(+string:stringtype+) 225 | !stringtype!.lastIndexOf(+string:stringtype+, +common:int+) 226 | !stringtype!.match(+regexp:regexptype+) 227 | !stringtype!.normalize() 228 | !stringtype!.normalize(+string:normalize_form+) 229 | !stringtype!.padEnd(+common:int+) 230 | !stringtype!.padEnd(+common:int+, +string:stringtype+) 231 | !stringtype!.padStart(+common:int+) 232 | !stringtype!.padStart(+common:int+, +string:stringtype+) 233 | !stringtype!.repeat(+common:short_int+) 234 | !stringtype!.replace(+string:stringtype+, +string:stringtype+) 235 | !stringtype!.replace(+regexp:regexptype+, "") 236 | !stringtype!.replace(+regexp:regexptype+, +string:stringtype+) 237 | !stringtype!.search(+regexp:regexptype+) 238 | !stringtype!.slice(+common:int+) 239 | !stringtype!.slice(+common:int+, +common:int+) 240 | !stringtype!.split() 241 | !stringtype!.split(+string:stringtype+) 242 | !stringtype!.split(+string:stringtype+, +common:int+) 243 | !stringtype!.startsWith(+string:stringtype+) 244 | !stringtype!.startsWith(+string:stringtype+, +common:int+) 245 | !stringtype!.substr(+common:int+) 246 | !stringtype!.substr(+common:int+, +common:int+) 247 | !stringtype!.substring(+common:int+) 248 | !stringtype!.substring(+common:int+, +common:int+) 249 | !stringtype!.toLocaleLowerCase() 250 | !stringtype!.toLocaleUpperCase() 251 | !stringtype!.toLowerCase() 252 | !stringtype!.toString() 253 | !stringtype!.toUpperCase() 254 | !stringtype!.trim() 255 | !stringtype!.trimStart() 256 | !stringtype!.trimLeft() 257 | !stringtype!.trimEnd() 258 | 259 | symbol := 260 | !symboltype!.toString() 261 | !symboltype!.valueOf() 262 | 263 | weakmap := 264 | !weakmaptype!.delete(+value:valtype+) 265 | !weakmaptype!.get(+value:valtype+) 266 | !weakmaptype!.has(+value:valtype+) 267 | !weakmaptype!.set(+value:valtype+, +value:valtype+) 268 | 269 | weakset := 270 | !weaksettype!.add(+value:valtype+) 271 | !weaksettype!.delete(+value:valtype+) 272 | !weaksettype!.has(+value:valtype+) 273 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/controls.dg: -------------------------------------------------------------------------------- 1 | LanguageConstructs := 2 | #actions#; return var0 3 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/arguments.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | argtype := 4 | (function foo() { return foo.arguments; })(%repeat%(+value:valtype+, ", ")) 5 | 6 | statement := 7 | +argtype+.callee 8 | +argtype+.length 9 | +argtype+.toString() 10 | +argtype+.toLocaleString() 11 | +argtype+.valueOf() 12 | +argtype+[+common:int+] 13 | +argtype+[+common:int+] = +value:valtype+ 14 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/array.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | any_arr := 4 | +arrtype+ 5 | 6 | 7 | statement := 8 | +any_arr+[+common:int+] 9 | +any_arr+[+common:decimal_number+] 10 | delete +any_arr+[+common:byte_int+] 11 | +any_arr+.length 12 | +any_arr+.length = +value:valtype+ 13 | +any_arr+.copyWithin(+common:int+) 14 | +any_arr+.copyWithin(+common:int+, +common:int+) 15 | +any_arr+.copyWithin(+common:int+, +common:int+, +common:int+) 16 | +any_arr+.fill(+value:valtype+) 17 | +any_arr+.fill(+value:valtype+, +common:int+) 18 | +any_arr+.fill(+value:valtype+, +common:int+, +common:int+) 19 | +any_arr+.pop() 20 | +any_arr+.push(+value:valtype+) 21 | +any_arr+.reverse() 22 | +any_arr+.shift() 23 | +any_arr+.sort(+callback:two_op_compare+) 24 | +any_arr+.splice(+common:int+, +common:int+, %repeat%(+value:valtype+, ", ")) 25 | +any_arr+.unshift(%repeat%(+value:valtype+, ", ")) 26 | +any_arr+.includes(+value:valtype+) 27 | +any_arr+.indexOf(+value:valtype+) 28 | +any_arr+.join() 29 | +any_arr+.join(+value:valtype+) 30 | +any_arr+.lastIndexOf(+value:valtype+) 31 | +any_arr+.entries() 32 | +any_arr+.slice() 33 | +any_arr+.slice(+common:int+) 34 | +any_arr+.slice(+common:int+, +common:int+) 35 | +any_arr+.toString() 36 | +any_arr+.toLocaleString() 37 | +any_arr+.toLocaleString(+intl:locale_str+) 38 | +any_arr+.every(+callback:one_op_predicate+) 39 | +any_arr+.filter(+callback:one_op_predicate+) 40 | +any_arr+.find(+callback:find_callback+) 41 | +any_arr+.findIndex(+callback:find_callback+) 42 | +any_arr+.forEach(+callback:one_op_predicate+) 43 | +any_arr+.keys() 44 | +any_arr+.map(+callback:map_callback+) 45 | +any_arr+.reduce(+callback:reduce_callback+, +value:valtype+) 46 | +any_arr+.reduceRight(+callback:reduce_callback+, +value:valtype+) 47 | +any_arr+.some(+callback:one_op_predicate+) 48 | +any_arr+.values() 49 | +any_arr+[+common:int+ % +any_arr+.length] 50 | +any_arr+[+common:int+ % +any_arr+.length] = +value:valtype+ 51 | +any_arr+[+common:int+] = +value:valtype+ 52 | +any_arr+[+common:decimal_number+] = +value:valtype+ 53 | 54 | arrtype := 55 | [%repeat%(+value:valtype+, ",")] 56 | [%repeat%(+common:decimal_number+, ",")] 57 | new Array(+common:short_int+) 58 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/boolean.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | booltype := 4 | true 5 | false 6 | Boolean(+value:valtype+) 7 | new Boolean(+value:valtype+) 8 | 9 | any_bool := 10 | +booltype+ 11 | 12 | statement := 13 | +any_bool+.toString() 14 | +any_bool+.valueOf() 15 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/buffer.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | arraybuffertype := 4 | new ArrayBuffer(+common:positive_integer+) 5 | 6 | typedarrayarg := 7 | +common:positive_integer+ 8 | +typedarraytype+ 9 | +arraybuffertype+ 10 | +arraybuffertype+, +common:positive_integer+ 11 | +arraybuffertype+, +common:positive_integer+, +common:positive_integer+ 12 | 13 | typedarraykind := 14 | Int8Array 15 | Uint8Array 16 | Uint8ClampedArray 17 | Int16Array 18 | Uint16Array 19 | Int32Array 20 | Uint32Array 21 | Float32Array 22 | Float64Array 23 | 24 | typedarraytype := 25 | new +typedarraykind+(+typedarrayarg+) 26 | 27 | any_arraybuffer := 28 | +arraybuffertype+ 29 | 30 | any_typedarray := 31 | +typedarraytype+ 32 | 33 | statement := 34 | ArrayBuffer.isView(+any_arraybuffer+) 35 | ArrayBuffer.transfer(+any_arraybuffer+) 36 | ArrayBuffer.transfer(+any_arraybuffer+, +common:int+) 37 | +any_arraybuffer+.slice(+common:positive_integer+) 38 | +any_arraybuffer+.slice(+common:positive_integer+, +common:positive_integer+) 39 | +any_typedarray+.buffer 40 | +any_typedarray+.byteLength 41 | +any_typedarray+.byteOffset 42 | +any_typedarray+.length 43 | +any_typedarray+.copyWithin(+common:positive_integer+, +common:positive_integer+) 44 | +any_typedarray+.copyWithin(+common:positive_integer+, +common:positive_integer+, +common:positive_integer+) 45 | +any_typedarray+.entries() 46 | +any_typedarray+.every(+callback:one_op_predicate+) 47 | +any_typedarray+.fill(+value:valtype+) 48 | +any_typedarray+.filter(+callback:one_op_predicate+) 49 | +any_typedarray+.find(+callback:find_callback+) 50 | +any_typedarray+.findIndex(+callback:find_callback+) 51 | +any_typedarray+.forEach(+callback:foreach_callback+) 52 | +any_typedarray+.includes(+value:valtype+) 53 | +any_typedarray+.includes(+value:valtype+, +common:positive_integer+) 54 | +any_typedarray+.indexOf(+value:valtype+) 55 | +any_typedarray+.indexOf(+value:valtype+, +common:positive_integer+) 56 | +any_typedarray+.join() 57 | +any_typedarray+.join(+value:valtype+) 58 | +any_typedarray+.keys() 59 | +any_typedarray+.lastIndexOf(+value:valtype+) 60 | +any_typedarray+.lastIndexOf(+value:valtype+, +common:positive_integer+) 61 | +any_typedarray+.map(+callback:map_callback+) 62 | +any_typedarray+.reduce(+callback:reduce_callback+, +value:valtype+) 63 | +any_typedarray+.reduceRight(+callback:reduce_callback+, +value:valtype+) 64 | +any_typedarray+.reverse() 65 | +any_typedarray+.set(+value:valtype+) 66 | +any_typedarray+.set(+value:valtype+, +common:positive_integer+) 67 | +any_typedarray+.slice() 68 | +any_typedarray+.slice(+common:integer+) 69 | +any_typedarray+.slice(+common:integer+, +common:integer+) 70 | +any_typedarray+.some(+callback:one_op_predicate+) 71 | +any_typedarray+.sort(+callback:two_op_compare+) 72 | +any_typedarray+.subarray() 73 | +any_typedarray+.subarray(+common:integer+, +common:integer+) 74 | +any_typedarray+.values() 75 | +any_typedarray+.toLocaleString() 76 | +any_typedarray+.toString() 77 | +any_typedarray+[Symbol.iterator]() 78 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/common.dg: -------------------------------------------------------------------------------- 1 | %%% Common Things 2 | 3 | %section% := value 4 | 5 | bool := 6 | true 7 | false 8 | 9 | digit := 10 | %range%(0-9) 11 | 12 | byte_int := 13 | %range%(0-255) 14 | 15 | short_int := 16 | %range%(0-65535) 17 | 18 | int := 19 | %range%(0-4294967295) 20 | 21 | sign := 22 | + 23 | - 24 | 25 | range_number := 26 | %range%(0-9) 27 | 1%range%(0-9) 28 | 12%range%(0-9) 29 | 25%range%(0-9) 30 | 204%range%(0-9) 31 | 3276%range%(0-9) 32 | 6553%range%(0-9) 33 | 214748364%range%(0-9) 34 | 429496729%range%(0-9) 35 | 36 | bad_number := 37 | +number+ 38 | +range_number+ 39 | 40 | positive_integer := 41 | +digit+ 42 | +byte_int+ 43 | +short_int+ 44 | +int+ 45 | 46 | integer := 47 | +positive_integer+ 48 | +sign++positive_integer+ 49 | 50 | digits := 51 | %repeat%(+digit+) 52 | +digit+ 53 | 54 | decimal_number := 55 | +integer+.+digits+ 56 | 57 | scientific_number := 58 | +decimal_number+e+integer+ 59 | +decimal_number+E+integer+ 60 | 61 | unit_identifier := 62 | pt 63 | pc 64 | cm 65 | mm 66 | in 67 | px 68 | em 69 | ex 70 | 71 | length := 72 | +integer+ 73 | +integer++unit_identifier+ 74 | 75 | number := 76 | +integer+ 77 | +decimal_number+ 78 | 79 | hex := 80 | %range%(0-9) 81 | %range%(A-F) 82 | 83 | byte := 84 | 0x+hex++hex+ 85 | 86 | character := 87 | %range%(a-z) 88 | %range%(A-Z) 89 | 90 | asciichar := 91 | %range%(!-~) 92 | 93 | text := 94 | %repeat%(+character+) 95 | 96 | font := 97 | Arial 98 | 99 | encoding := 100 | ascii 101 | utf8 102 | utf16le 103 | ucs2 104 | base64 105 | binary 106 | hex 107 | 108 | image_mime_type := 109 | "image/gif" 110 | "image/png" 111 | "image/jpeg" 112 | "image/webp" 113 | "image/svg+xml" 114 | 115 | audio_mime_type := 116 | "audio/ogg" 117 | "audio/mpeg" 118 | "audio/ogg; codecs='vorbis'" 119 | 120 | video_mime_type := 121 | "video/ogg" 122 | "video/ogg; codecs='theora,vorbis'" 123 | "video/mp4" 124 | "video/mp4; codecs='avc1.42E01E,mp4a.40.2'" 125 | "video/webm; codecs='vorbis,vp8'" 126 | 127 | text_mime_type := 128 | "text/html" 129 | "text/plain" 130 | "text/css" 131 | "text/javascript" 132 | 133 | app_mime_type := 134 | "application/xhtml+xml" 135 | "application/octet-stream" 136 | "application/x-shockwave-flash" 137 | 138 | mime_type := 139 | +image_mime_type+ 140 | +audio_mime_type+ 141 | +video_mime_type+ 142 | +text_mime_type+ 143 | +app_mime_type+ 144 | 145 | audio_codecs := 146 | "vorbis" 147 | 148 | video_codecs := 149 | "webm" 150 | "vp8" 151 | "vp9" 152 | "theora" 153 | 154 | codecs := 155 | +audio_codecs+ 156 | +video_codecs+ 157 | 158 | color := 159 | red 160 | green 161 | blue 162 | #555 163 | #333 164 | #222 165 | rgb(%range%(0-255), %range%(0-255), %range%(0-255)) 166 | rgba(%range%(0-255), %range%(0-255), %range%(0-255), +number+) 167 | hsl(+number+, %range%(0-100)% %range%(0-100)%) 168 | hsla(+number+, %range%(0-100)% %range%(0-100)%, +number+) 169 | 170 | object := 171 | [] 172 | {} 173 | function() {} 174 | new Object() 175 | undefined 176 | null 177 | "+text+" 178 | 179 | intoverflow := 180 | 0 181 | 1 182 | 32768 183 | 65535 184 | 65536 185 | 357913942 186 | 2147483648 187 | 4294967296 188 | 8446744073709551616 189 | -0 190 | -1 191 | -32768 192 | -65535 193 | -65536 194 | -357913942 195 | -2147483648 196 | -4294967296 197 | -8446744073709551616 198 | 0xff 199 | 0x3fffffff 200 | 0xffffffff 201 | 0xfffffffe 202 | 0x100 203 | 0x1000 204 | 0x10000 205 | 0x100000 206 | 0x80000000 207 | 208 | formatstr := 209 | %repeat%(%s) 210 | %repeat%(%x) 211 | %repeat%(%d) 212 | AAAAA%s 213 | AAAAA%x 214 | AAAAA%d 215 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/dataview.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | dataviewbuffer := 4 | +buffer:arraybuffertype+ 5 | 6 | dataviewtype := 7 | (new DataView(+dataviewbuffer+)) 8 | (new DataView(+dataviewbuffer+, +common:int+)) 9 | (new DataView(+dataviewbuffer+, +common:int+, +common:int+)) 10 | 11 | any_dataview := 12 | +dataviewtype+ 13 | 14 | dataviewidx := 15 | +common:byte_int+ 16 | +common:int+ 17 | 18 | get_args := 19 | +dataviewidx+ 20 | +dataviewidx+, +common:bool+ 21 | 22 | set_args := 23 | +dataviewidx+, +common:number+ 24 | +dataviewidx+, +common:number+, +common:bool+ 25 | 26 | statement := 27 | +any_dataview+.buffer 28 | +any_dataview+.buffer = +dataviewbuffer+ 29 | +any_dataview+.byteLength 30 | +any_dataview+.byteLength = +common:int+ 31 | +any_dataview+.byteOffset 32 | +any_dataview+.byteOffset = +common:int+ 33 | +any_dataview+.getInt8(+get_args+) 34 | +any_dataview+.getUInt8(+get_args+) 35 | +any_dataview+.getInt16(+get_args+) 36 | +any_dataview+.getUInt16(+get_args+) 37 | +any_dataview+.getInt32(+get_args+) 38 | +any_dataview+.getUInt32(+get_args+) 39 | +any_dataview+.getFloat32(+get_args+) 40 | +any_dataview+.getFloat64(+get_args+) 41 | +any_dataview+.setInt8(+set_args+) 42 | +any_dataview+.setUInt8(+set_args+) 43 | +any_dataview+.setInt16(+set_args+) 44 | +any_dataview+.setUInt16(+set_args+) 45 | +any_dataview+.setInt32(+set_args+) 46 | +any_dataview+.setUInt32(+set_args+) 47 | +any_dataview+.setFloat32(+set_args+) 48 | +any_dataview+.setFloat64(+set_args+) 49 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/date.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | datetype := 4 | Date() 5 | Date.parse("+common:text+") 6 | new Date() 7 | new Date(+common:int+) 8 | new Date(+common:int+, +common:int+) 9 | new Date(+common:int+, +common:int+, +common:int+) 10 | new Date(+common:int+, +common:int+, +common:int+, +common:int+) 11 | new Date(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 12 | new Date(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 13 | new Date.UTC() 14 | new Date.UTC(+common:int+) 15 | new Date.UTC(+common:int+, +common:int+) 16 | new Date.UTC(+common:int+, +common:int+, +common:int+) 17 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+) 18 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 19 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 20 | 21 | 22 | statement := 23 | Date.now() 24 | !date!.getDate() 25 | !date!.getDay() 26 | !date!.dateFullYear() 27 | !date!.getHours() 28 | !date!.getMilliseconds() 29 | !date!.getMinutes() 30 | !date!.getMonth() 31 | !date!.getSeconds() 32 | !date!.getTime() 33 | !date!.getTimezoneOffset() 34 | !date!.getUTCDate() 35 | !date!.getUTCDay() 36 | !date!.getUTCFullYear() 37 | !date!.getUTCHours() 38 | !date!.getUTCMilliseconds() 39 | !date!.getUTCMinutes() 40 | !date!.getUTCMonth() 41 | !date!.getUTCSeconds() 42 | !date!.getYear() 43 | !date!.setDate(+common:int+) 44 | !date!.setFullYear(+common:int+) 45 | !date!.setHours(+common:int+) 46 | !date!.setMilliseconds(+common:int+) 47 | !date!.setMinutes(+common:int+) 48 | !date!.setMonth(+common:int+) 49 | !date!.setSeconds(+common:int+) 50 | !date!.setTime(+common:int+) 51 | !date!.setUTCDate(+common:int+) 52 | !date!.setUTCFullYear(+common:int+) 53 | !date!.setUTCHours(+common:int+) 54 | !date!.setUTCMilliseconds(+common:int+) 55 | !date!.setUTCMinutes(+common:int+) 56 | !date!.setUTCMonth(+common:int+) 57 | !date!.setUTCSeconds(+common:int+) 58 | !date!.setYear(+common:int+) 59 | !date!.toDateSTring() 60 | !date!.toISOString() 61 | !date!.toJSON() 62 | !date!.toGMTString() 63 | !date!.toLocaleDateString() 64 | !date!.toLocaleString() 65 | !date!.toLocaleTimeString() 66 | !date!.toString() 67 | !date!.toTimeString() 68 | !date!.toUTCString() 69 | !date!.valueOf() 70 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/globals.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | %%% boring global functions 4 | 5 | statement := 6 | decodeURI("+common:text+") 7 | decodeURIComponent("+common:text+") 8 | encodeURI("+common:text+") 9 | encodeURIComponent("+common:text+") 10 | isFinite(+common:number+) 11 | isNaN(+common:number+) 12 | parseFloat("+common:number+") 13 | parseInt("+common:number+") 14 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/intl.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | locale_str := 4 | "en" 5 | "en-US" 6 | "hi" 7 | "de-AT" 8 | "zh-Hans-CN" 9 | "de-DE-u-co-phonebk" 10 | "th-TH-u-nu-thai" 11 | "ja-JP-u-ca-japanese" 12 | "en-GB-u-ca-islamic" 13 | "af-ZA" 14 | "am-ET" 15 | "ar-AE" 16 | "ar-BH" 17 | "ar-DZ" 18 | "ar-EG" 19 | "ar-IQ" 20 | "ar-JO" 21 | "ar-KW" 22 | "ar-LB" 23 | "ar-LY" 24 | "ar-MA" 25 | "arn-CL" 26 | "ar-OM" 27 | "ar-QA" 28 | "ar-SA" 29 | "ar-SY" 30 | "ar-TN" 31 | "ar-YE" 32 | "as-IN" 33 | "az-Cyrl-AZ" 34 | "az-Latn-AZ" 35 | "ba-RU" 36 | "be-BY" 37 | "bg-BG" 38 | "bn-BD" 39 | "bn-IN" 40 | "bo-CN" 41 | "br-FR" 42 | "bs-Cyrl-BA" 43 | "bs-Latn-BA" 44 | "ca-ES" 45 | "co-FR" 46 | "cs-CZ" 47 | "cy-GB" 48 | "da-DK" 49 | "de-AT" 50 | "de-CH" 51 | "de-DE" 52 | "de-LI" 53 | "de-LU" 54 | "dsb-DE" 55 | "dv-MV" 56 | "el-GR" 57 | "en-029" 58 | "en-AU" 59 | "en-BZ" 60 | "en-CA" 61 | "en-GB" 62 | "en-IE" 63 | "en-IN" 64 | "en-JM" 65 | "en-MY" 66 | "en-NZ" 67 | "en-PH" 68 | "en-SG" 69 | "en-TT" 70 | "en-US" 71 | "en-ZA" 72 | "en-ZW" 73 | "es-AR" 74 | "es-BO" 75 | "es-CL" 76 | "es-CO" 77 | "es-CR" 78 | "es-DO" 79 | "es-EC" 80 | "es-ES" 81 | "es-GT" 82 | "es-HN" 83 | "es-MX" 84 | "es-NI" 85 | "es-PA" 86 | "es-PE" 87 | "es-PR" 88 | "es-PY" 89 | "es-SV" 90 | "es-US" 91 | "es-UY" 92 | "es-VE" 93 | "et-EE" 94 | "eu-ES" 95 | "fa-IR" 96 | "fi-FI" 97 | "fil-PH" 98 | "fo-FO" 99 | "fr-BE" 100 | "fr-CA" 101 | "fr-CH" 102 | "fr-FR" 103 | "fr-LU" 104 | "fr-MC" 105 | "fy-NL" 106 | "ga-IE" 107 | "gd-GB" 108 | "gl-ES" 109 | "gsw-FR" 110 | "gu-IN" 111 | "ha-Latn-NG" 112 | "he-IL" 113 | "hi-IN" 114 | "hr-BA" 115 | "hr-HR" 116 | "hsb-DE" 117 | "hu-HU" 118 | "hy-AM" 119 | "id-ID" 120 | "ig-NG" 121 | "ii-CN" 122 | "is-IS" 123 | "it-CH" 124 | "it-IT" 125 | "iu-Cans-CA" 126 | "iu-Latn-CA" 127 | "ja-JP" 128 | "ka-GE" 129 | "kk-KZ" 130 | "kl-GL" 131 | "km-KH" 132 | "kn-IN" 133 | "kok-IN" 134 | "ko-KR" 135 | "ky-KG" 136 | "lb-LU" 137 | "lo-LA" 138 | "lt-LT" 139 | "lv-LV" 140 | "mi-NZ" 141 | "mk-MK" 142 | "ml-IN" 143 | "mn-MN" 144 | "mn-Mong-CN" 145 | "moh-CA" 146 | "mr-IN" 147 | "ms-BN" 148 | "ms-MY" 149 | "mt-MT" 150 | "nb-NO" 151 | "ne-NP" 152 | "nl-BE" 153 | "nl-NL" 154 | "nn-NO" 155 | "nso-ZA" 156 | "oc-FR" 157 | "or-IN" 158 | "pa-IN" 159 | "pl-PL" 160 | "prs-AF" 161 | "ps-AF" 162 | "pt-BR" 163 | "pt-PT" 164 | "qut-GT" 165 | "quz-BO" 166 | "quz-EC" 167 | "quz-PE" 168 | "rm-CH" 169 | "ro-RO" 170 | "ru-RU" 171 | "rw-RW" 172 | "sah-RU" 173 | "sa-IN" 174 | "se-FI" 175 | "se-NO" 176 | "se-SE" 177 | "si-LK" 178 | "sk-SK" 179 | "sl-SI" 180 | "sma-NO" 181 | "sma-SE" 182 | "smj-NO" 183 | "smj-SE" 184 | "smn-FI" 185 | "sms-FI" 186 | "sq-AL" 187 | "sr-Cyrl-BA" 188 | "sr-Cyrl-CS" 189 | "sr-Cyrl-ME" 190 | "sr-Cyrl-RS" 191 | "sr-Latn-BA" 192 | "sr-Latn-CS" 193 | "sr-Latn-ME" 194 | "sr-Latn-RS" 195 | "sv-FI" 196 | "sv-SE" 197 | "sw-KE" 198 | "syr-SY" 199 | "ta-IN" 200 | "te-IN" 201 | "tg-Cyrl-TJ" 202 | "th-TH" 203 | "tk-TM" 204 | "tn-ZA" 205 | "tr-TR" 206 | "tt-RU" 207 | "tzm-Latn-DZ" 208 | "ug-CN" 209 | "uk-UA" 210 | "ur-PK" 211 | "uz-Cyrl-UZ" 212 | "uz-Latn-UZ" 213 | "vi-VN" 214 | "wo-SN" 215 | "xh-ZA" 216 | "yo-NG" 217 | "zh-CN" 218 | "zh-HK" 219 | "zh-MO" 220 | "zh-SG" 221 | "zh-TW" 222 | "zu-ZA" 223 | 224 | 225 | locale_matcher := 226 | "lookup" 227 | "best fit" 228 | 229 | collator_usage := 230 | "sort" 231 | "search" 232 | 233 | collator_sensitivity := 234 | "base" 235 | "accent" 236 | "case" 237 | "variant" 238 | 239 | collator_case_first := 240 | "upper" 241 | "lower" 242 | "false" 243 | 244 | collator_option_pairs := 245 | localeMatcher: +locale_matcher+ 246 | usage: +collator_usage+ 247 | sensitivity: +collator_sensitivity+ 248 | ignorePunctuation: +common:bool+ 249 | numeric: +common:bool+ 250 | caseFirst: +collator_case_first+ 251 | 252 | collator_options := 253 | { %repeat%(+collator_option_pairs+, ",") } 254 | 255 | collator := 256 | (new Intl.Collator(+locale_str+, +collator_options+)) 257 | 258 | collator_statement := 259 | +collator+.compare("+common:character+", "+common:character+") 260 | +collator+.resolvedOptions() 261 | 262 | date_time_format := 263 | (new Intl.DateTimeFormat(+locale_str+)) 264 | 265 | date_time_format_statement := 266 | Intl.DateTimeFormat.supportedLocalesOf(+locale_str+) 267 | +date_time_format+.format(!date:date!) 268 | +date_time_format+.formatToParts(!date:date!) 269 | +date_time_format+.resolvedOptions() 270 | 271 | numbering_system := 272 | "arab" 273 | "arabext" 274 | "bali" 275 | "beng" 276 | "deva" 277 | "fullwide" 278 | "gujr" 279 | "guru" 280 | "hanidec" 281 | "khmr" 282 | "knda" 283 | "laoo" 284 | "latn" 285 | "limb" 286 | "mlym" 287 | "mong" 288 | "mymr" 289 | "orya" 290 | "tamldec" 291 | "telu" 292 | "thai" 293 | "tibt" 294 | 295 | number_format_style := 296 | "decimal" 297 | "currency" 298 | "percent" 299 | 300 | %%% very incomplete list 301 | number_format_currency := 302 | "USD" 303 | "EUR" 304 | "CNY" 305 | 306 | number_format_currency_display := 307 | "symbol" 308 | "code" 309 | "name" 310 | 311 | number_format_option_pairs := 312 | localeMatcher: +locale_matcher+ 313 | style: +number_format_style+ 314 | currency: +number_format_currency+ 315 | currencyDisplay: +number_format_currency_display+ 316 | useGrouping: +common:bool+ 317 | minimumIntegerDigits: %range%(1-21) 318 | minimumFractionDigits: %range%(0-20) 319 | maximumFractionDigits: %range%(0-20) 320 | minimumSignificantDigits: %range%(1-21) 321 | maximumSignificantDigits: %range%(1-21) 322 | 323 | number_format_options := 324 | { %repeat%(+number_format_option_pairs+, ",") } 325 | 326 | number_format := 327 | (new Intl.NumberFormat(+locale_str+, +number_format_options+)) 328 | 329 | number_format_statement := 330 | Intl.NumberFormat.supportedLocalesOf() 331 | +number_format+.format(+common:number+) 332 | +number_format+.formatToParts(+common:number+) 333 | +number_format+.resolvedOptions() 334 | 335 | plural_rules_type := 336 | "cardinal" 337 | "ordinal" 338 | 339 | plural_rules_option_pairs := 340 | localeMatcher: +locale_matcher+ 341 | type: +plural_rules_type+ 342 | 343 | plural_rules_options := 344 | { %repeat%(+plural_rules_option_pairs+, ",") } 345 | 346 | plural_rules := 347 | (new Intl.PluralRules(+locale_str+, +plural_rules_options+)) 348 | 349 | plural_rules_statement := 350 | Intl.PluralRules.supportedLocalesOf() 351 | +plural_rules+.resolvedOptions() 352 | +plural_rules+.select(+common:number+) 353 | 354 | statement := 355 | Intl.getCanonicalLocales() 356 | +collator_statement+ 357 | +date_time_format_statement+ 358 | +number_format_statement+ 359 | +plural_rules_statement+ 360 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/map.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | value_pair := 4 | [+value:valtype+, +value:valtype+] 5 | 6 | map_arg := 7 | +value:valtype+ 8 | [] 9 | [+value_pair+] 10 | [ %repeat%(+value_pair+, ", ") ] 11 | 12 | maptype := 13 | new Map(+map_arg+) 14 | 15 | any_map := 16 | +maptype+ 17 | 18 | statement := 19 | +any_map+.size 20 | +any_map+.clear() 21 | +any_map+.delete(+value:valtype+) 22 | +any_map+.entries() 23 | +any_map+.forEach(+callback:foreach_callback+) 24 | +any_map+.get(+value:valtype+) 25 | +any_map+.has(+value:valtype+) 26 | +any_map+.keys() 27 | +any_map+.set(+value:valtype+, +value:valtype+) 28 | +any_map+.values() 29 | +any_map+[Symbol.iterator]() 30 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/math.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | constant := 4 | Math.E 5 | Math.LN2 6 | Math.LN10 7 | Math.LOG2E 8 | Math.LOG10E 9 | Math.PI 10 | Math.SQRT1_2 11 | Math.SQRT2 12 | -0.5 13 | 0.5 14 | -0 15 | 0 16 | NaN 17 | Infinity 18 | Number.NEGATIVE_INFINITY 19 | 20 | num := 21 | +common:number+ 22 | +constant+ 23 | 24 | statement := 25 | Math.abs(+num+) 26 | Math.acos(+num+) 27 | Math.acosh(+num+) 28 | Math.asin(+num+) 29 | Math.asinh(+num+) 30 | Math.atan(+num+) 31 | Math.atanh(+num+) 32 | Math.atan2(+num+, +num+) 33 | Math.cbrt(+num+) 34 | Math.ceil(+num+) 35 | Math.clz32(+num+) 36 | Math.cos(+num+) 37 | Math.conh(+num+) 38 | Math.exp(+num+) 39 | Math.expm1(+num+) 40 | Math.floor(+num+) 41 | Math.fround(+num+) 42 | Math.hypot(%repeat%(+num+, ", ")) 43 | Math.imul(+num+, +num+) 44 | Math.log(+num+) 45 | Math.log1p(+num+) 46 | Math.log10(+num+) 47 | Math.log2(+num+) 48 | Math.max(%repeat%(+num+, ", ")) 49 | Math.min(%repeat%(+num+, ", ")) 50 | Math.pow(+num+, +num+) 51 | Math.random() 52 | Math.round(+num+) 53 | Math.sign(+num+) 54 | Math.sin(+num+) 55 | Math.sinh(+num+) 56 | Math.sqrt(+num+) 57 | Math.tan(+num+) 58 | Math.tanh(+num+) 59 | Math.trunc(+num+) 60 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/number.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | numbertype := 4 | new Number(+value:valtype+) 5 | new Number(+common:int+) 6 | new Number("+common:int+") 7 | Number(+value:valtype+) 8 | Number(+common:int+) 9 | Number("+common:int+") 10 | Number.EPSILON 11 | Number.MAX_SAFE_INTEGER 12 | Number.MAX_VALUE 13 | Number.MIN_SAFE_INTEGER 14 | Number.MIN_VALUE 15 | Number.NaN 16 | Number.NEGATIVE_INFINITY 17 | Number.POSITIVE_INFINITY 18 | 19 | statement := 20 | Number.isNaN(+value:valtype+) 21 | Number.isFinite(+value:valtype+) 22 | Number.isInteger(+value:valtype+) 23 | Number.isSafeInteger(+value:valtype+) 24 | Number.parseFloat(+value:valtype+) 25 | Number.parseInt(+value:valtype+) 26 | !number!.toExponential() 27 | !number!.toExponential(+common:byte_int+) 28 | !number!.toFixed() 29 | !number!.toFixed(+common:byte_int+) 30 | !number!.toLocaleString() 31 | !number!.toPrecision() 32 | !number!.toPrecision(+common:byte_int+) 33 | !number!.toString() 34 | !number!.toString(+common:byte_int+) 35 | !number!.toString(%range%(0-36)) 36 | !number!.valueOf() 37 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/object.dg: -------------------------------------------------------------------------------- 1 | %%% JSObjects 2 | 3 | %section% := value 4 | 5 | any_object := 6 | +value:valtype+ 7 | 8 | name_value_pair := 9 | "+common:text+": +value:valtype+ 10 | 11 | objtype := 12 | {%repeat%(+name_value_pair+, ",")} 13 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/reflect.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | arglist := 4 | +array:arrtype+ 5 | 6 | attributes := 7 | { value: +value:valtype+ } 8 | 9 | property := 10 | "length" 11 | "toString" 12 | "valueOf" 13 | "__proto__" 14 | "+common:text+" 15 | 16 | prototype := 17 | null 18 | +value:valtype+ 19 | 20 | statement := 21 | Reflect.apply(+value:valtype+, +value:valtype+, +arglist+) 22 | Reflect.construct(+value:valtype+, +arglist+) 23 | Reflect.construct(+value:valtype+, +arglist+, +value:valtype+) 24 | Reflect.defineProperty(+value:valtype+, +property+, +attributes+) 25 | Reflect.deleteProperty(+value:valtype+, +property+) 26 | Reflect.get(+value:valtype+, +property+) 27 | Reflect.get(+value:valtype+, +property+, +value:valtype+) 28 | Reflect.getOwnPropertyDescriptor(+value:valtype+, +property+) 29 | Reflect.getPrototypeOf(+value:valtype+) 30 | Reflect.has(+value:valtype+, +property+) 31 | Reflect.isExtensible(+value:valtype+) 32 | Reflect.ownKeys(+value:valtype+) 33 | Reflect.preventExtensions(+value:valtype+) 34 | Reflect.set(+value:valtype+, +property+, +value:valtype+) 35 | Reflect.set(+value:valtype+, +property+, +value:valtype+, +value:valtype+) 36 | Reflect.setPrototypeOf(+value:valtype+, +prototype+) 37 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/regexp.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | patternchar := 4 | +common:character+ 5 | . 6 | \d 7 | \D 8 | \w 9 | \W 10 | \s 11 | \S 12 | \t 13 | \r 14 | \v 15 | \f 16 | [\b] 17 | \0 18 | \c%range%(A-Z) 19 | \x+common:hex++common:hex+ 20 | \u+common:hex++common:hex++common:hex++common:hex+ 21 | \\ 22 | [a-z] 23 | [^abc] 24 | | 25 | ^ 26 | $ 27 | \b 28 | \B 29 | \+common:int+ 30 | (?:+pattern+) 31 | +pattern+* 32 | +pattern++ 33 | +pattern+? 34 | +pattern+{+common:int+} 35 | +pattern+{+common:int+,} 36 | +pattern+{+common:int+,+common:int+} 37 | +pattern+(?=+pattern+) 38 | +pattern+(?!+pattern+) 39 | 40 | pattern := 41 | %repeat%(+patternchar+, "") 42 | 43 | flagchar := 44 | g 45 | i 46 | m 47 | s 48 | u 49 | y 50 | 51 | 52 | flags := 53 | %unique%(+flagchar+) 54 | 55 | statement := 56 | !regexp!.flags = "+flags+" 57 | !regexp!.flags 58 | !regexp!.global = +common:bool+ 59 | !regexp!.global 60 | !regexp!.ignoreCase = +common:bool+ 61 | !regexp!.ignoreCase 62 | !regexp!.multiline = +common:bool+ 63 | !regexp!.multiline 64 | !regexp!.sticky = +common:bool+ 65 | !regexp!.sticky 66 | !regexp!.unicode = +common:bool+ 67 | !regexp!.unicode 68 | !regexp!.exec("+common:text+") 69 | !regexp!.test("+common:text+") 70 | RegExp.prototype[Symbol.match]("+common:text+") 71 | RegExp.prototype[Symbol.search]("+common:text+") 72 | RegExp.prototype[Symbol.split]("+common:text+") 73 | !regexp!.toString() 74 | !regexp!.lastIndex 75 | !regexp!.compile() 76 | "+common:text+".split(!regexp!) 77 | "+common:text+".split(!regexp!, +common:int+) 78 | 79 | regexptype := 80 | new RegExp("+pattern+", "+flags+") 81 | new RegExp("+pattern+") 82 | RegExp("+pattern+", "+flags+") 83 | RegExp("+pattern+") 84 | 85 | %section% := variable 86 | 87 | regexp := 88 | var @regexp@ = +regexptype+; 89 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/set.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | set_arg := 4 | +value:valtype+ 5 | [ %repeat%(+value:valtype+, ", ") ] 6 | 7 | settype := 8 | new Set(+set_arg+) 9 | 10 | any_set := 11 | +settype+ 12 | 13 | statement := 14 | +any_set+.size 15 | +any_set+.add(+value:valtype+) 16 | +any_set+.clear() 17 | +any_set+.delete(+value:valtype+) 18 | +any_set+.entries() 19 | +any_set+.forEach(+callback:foreach_callback+) 20 | +any_set+.has(+value:valtype+) 21 | +any_set+.keys() 22 | +any_set+.values() 23 | +any_set+[Symbol.iterator]() 24 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/string.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | normalize_form := 4 | "NFC" 5 | "NFD" 6 | "NFKC" 7 | "NFKD" 8 | "foo" 9 | 10 | stringtype := 11 | "+common:text+" 12 | new String("+common:text+") 13 | 14 | 15 | any_string := 16 | +stringtype+ 17 | 18 | statement := 19 | String.fromCharCode(%repeat%(+common:short_int+, ", ")) 20 | String.fromCodePoint(%repeat%(+common:int+, ", ")) 21 | +any_string+.charAt(+common:int+) 22 | +any_string+.charAt(+common:byte_int+) 23 | +any_string+.charCodeAt(+common:int+) 24 | +any_string+.charCodeAt(+common:byte_int+) 25 | +any_string+.codePointAt(+common:int+) 26 | +any_string+.codePointAt(+common:byte_int+) 27 | +any_string+.concat(+stringtype+) 28 | +any_string+.includes(+stringtype+) 29 | +any_string+.endsWith(+stringtype+) 30 | +any_string+.indexOf(+stringtype+) 31 | +any_string+.indexOf(+stringtype+, +common:int+) 32 | +any_string+.lastIndexOf(+stringtype+) 33 | +any_string+.lastIndexOf(+stringtype+, +common:int+) 34 | +any_string+.match(+regexp:regexptype+) 35 | +any_string+.normalize() 36 | +any_string+.normalize(+normalize_form+) 37 | +any_string+.padEnd(+common:int+) 38 | +any_string+.padEnd(+common:int+, +stringtype+) 39 | +any_string+.padStart(+common:int+) 40 | +any_string+.padStart(+common:int+, +stringtype+) 41 | +any_string+.repeat(+common:short_int+) 42 | +any_string+.replace(+stringtype+, +stringtype+) 43 | +any_string+.replace(+stringtype+, +callback:string_replace_callback+) 44 | +any_string+.replace(+regexp:regexptype+, "") 45 | +any_string+.replace(+regexp:regexptype+, +stringtype+) 46 | +any_string+.replace(+regexp:regexptype+, +callback:string_replace_callback+) 47 | +any_string+.search(+regexp:regexptype+) 48 | +any_string+.slice(+common:int+) 49 | +any_string+.slice(+common:int+, +common:int+) 50 | +any_string+.split() 51 | +any_string+.split(+stringtype+) 52 | +any_string+.split(+stringtype+, +common:int+) 53 | +any_string+.startsWith(+stringtype+) 54 | +any_string+.startsWith(+stringtype+, +common:int+) 55 | +any_string+.substr(+common:int+) 56 | +any_string+.substr(+common:int+, +common:int+) 57 | +any_string+.substring(+common:int+) 58 | +any_string+.substring(+common:int+, +common:int+) 59 | +any_string+.toLocaleLowerCase() 60 | +any_string+.toLocaleLowerCase(+intl:locale_str+) 61 | +any_string+.toLocaleLowerCase([%repeat%(+intl:locale_str+, ", ")]) 62 | +any_string+.toLocaleUpperCase() 63 | +any_string+.toLocaleUpperCase(+intl:locale_str+) 64 | +any_string+.toLocaleUpperCase([%repeat%(+intl:locale_str+, ", ")]) 65 | +any_string+.toLowerCase() 66 | +any_string+.toString() 67 | +any_string+.toUpperCase() 68 | +any_string+.trim() 69 | +any_string+.trimStart() 70 | +any_string+.trimLeft() 71 | +any_string+.trimEnd() 72 | +any_string+.trimRight() 73 | +any_string+.valueOf() 74 | +any_string+[Symbol.iterator]() 75 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/symbol.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | symboltype := 4 | Symbol.iterator 5 | Symbol.match 6 | Symbol.replace 7 | Symbol.search 8 | Symbol.split 9 | Symbol.hasInstance 10 | Symbol.isConcatSpreadable 11 | Symbol.unscopables 12 | Symbol.species 13 | Symbol.toPrimitive 14 | Symbol.toStringTag 15 | 16 | statement := 17 | !symbol!.toString() 18 | !symbol!.valueOf() 19 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/value.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | nulls := 4 | undefined 5 | null 6 | 7 | valtype := 8 | +nulls+ 9 | +common:int+ 10 | +common:decimal_number+ 11 | +common:short_int+ 12 | +common:intoverflow+ 13 | +common:byte+ 14 | +common:object+ 15 | +common:bool+ 16 | "+common:text+" 17 | +array:arrtype+ 18 | +object:objtype+ 19 | +symbol:symboltype+ 20 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/weakmap.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | keypair := 4 | [+value:valtype+, +value:valtype+] 5 | 6 | weakmaparg := 7 | +value:nulls+ 8 | [%repeat%(+keypair+, ", ")] 9 | 10 | weakmaptype := 11 | (new WeakMap(+weakmaparg+)) 12 | 13 | any_weakmap := 14 | +weakmaptype+ 15 | 16 | statement := 17 | +any_weakmap+.delete(+value:valtype+) 18 | +any_weakmap+.get(+value:valtype+) 19 | +any_weakmap+.has(+value:valtype+) 20 | +any_weakmap+.set(+value:valtype+, +value:valtype+) 21 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/dependencies/weakset.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | weaksetarg := 4 | +value:nulls+ 5 | [ %repeat%(+value:valtype+, ", ") ] 6 | 7 | weaksettype := 8 | (new WeakSet(+weaksetarg+)) 9 | 10 | any_weakset := 11 | +weaksettype+ 12 | 13 | statement := 14 | +any_weakset+.add(+value:valtype+) 15 | +any_weakset+.delete(+value:valtype+) 16 | +any_weakset+.has(+value:valtype+) 17 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/control_flow.dg: -------------------------------------------------------------------------------- 1 | Grammer := 2 | +IfStatement+ 3 | +IterationStatement+ 4 | +ForDeclaration+ 5 | 6 | IfStatement := 7 | if ( +Expression+ ) +value+ else +value+ 8 | if ( +Expression+ ) +value+ 9 | 10 | IterationStatement := 11 | do +value+ while ( +value+ ); 12 | while ( +value+ ) +value+ 13 | for ( +value+ ; +value+ ; +value+ ) { +value+; } 14 | 15 | ForDeclaration := 16 | +values:LetOrConst+ +ForBinding+ 17 | 18 | ForBinding := 19 | +values:BindingIdentifier+ 20 | +values:BindingPattern+ 21 | 22 | ContinueStatement := 23 | continue; 24 | continue +value+; 25 | 26 | BreakStatement := 27 | break; 28 | break +values:LabelIdentifier+ ; 29 | 30 | ReturnStatement := 31 | return ; 32 | return +value+ ; 33 | 34 | WithStatement := 35 | with ( +Expression+ ) +values:Statement+ 36 | 37 | SwitchStatement := 38 | switch ( +common:int+ ) +values:CaseBlock+ 39 | 40 | ThrowStatement := 41 | throw +Value+ ; 42 | 43 | TryStatement := 44 | try +Block+ +Catch+ 45 | try +Block+ +Finally+ 46 | try +Block+ +Catch+ finally 47 | 48 | Catch := 49 | catch ( ) +value+ 50 | 51 | Finally := 52 | finally +value+ 53 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/ecma1.dg: -------------------------------------------------------------------------------- 1 | %%% LanguageConstructs API 2 | 3 | %const% VARIANCE_MAX := 1 4 | %const% VARIANCE_TEMPLATE := "function f(){%s} %%DebugPrint(f()); %%OptimizeFunctionOnNextCall(f); %%DebugPrint(f());" 5 | %const% MAX_REPEAT_POWER := 4 6 | 7 | %section% := value 8 | 9 | %%% ########################################################################### 10 | 11 | weird_type := 12 | null 13 | undefined 14 | NaN 15 | 16 | symbol := 17 | Symbol( %repeat%(+common:object+, ", ") ) 18 | 19 | numParsing := 20 | parseInt(+grammar:intArgs+) 21 | parseFloat(+grammar:intArgs+) 22 | parseInt(+grammar:builtinMath+) 23 | parseFloat(+grammar:builtinMath+) 24 | parseInt(+weird_type+) 25 | parseFloat(+weird_type+) 26 | 27 | conditionalOR := 28 | ( (+common:bool+) || (+common:bool+) ) 29 | 30 | assignmentOperator := 31 | *= 32 | /=" 33 | %= 34 | += 35 | -= 36 | <<= 37 | >>= 38 | >>>= 39 | &= 40 | ^= 41 | |= 42 | 43 | setAvailableVars := 44 | var a; var b; var c; var d; var e; var f; 45 | 46 | availableVars := 47 | a 48 | b 49 | c 50 | d 51 | e 52 | f 53 | 54 | assignmentExpr := 55 | +conditionalExpr+ 56 | +availableVars = +assignmentExpr+ 57 | +availableVars+ +assignmentOperator+ +assignmentExpr+ 58 | 59 | conditionalExpr := 60 | +conditionalOR+ 61 | +conditionalOR+ ? +assignmentExpr+ : +assignmentExpr+ 62 | 63 | Expression := 64 | +assignmentExpr+ 65 | +Expression+ +assignmentExpr+ 66 | 67 | %%% ########################################################################### 68 | 69 | %section% := variance 70 | main := 71 | +setAvailableVars+ +Expression+; return +weird_type+ 72 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/es6.dg: -------------------------------------------------------------------------------- 1 | Grammer := 2 | +Statement+ 3 | 4 | SourceCharacter := 5 | x000000 6 | x10FFFF 7 | 8 | InputElementDiv := 9 | +WhiteSpace+ 10 | +LineTerminator+ 11 | +CommonToken+ 12 | +DivPunctuator+ 13 | +RightBracePunctuator+ 14 | 15 | InputElementRegExp := 16 | +WhiteSpace+ 17 | +LineTerminator+ 18 | +CommonToken+ 19 | +RightBracePunctuator+ 20 | +RegularExpressionLiteral+ 21 | 22 | InputElementRegExpOrTemplateTail := 23 | +WhiteSpace+ 24 | +LineTerminator+ 25 | +CommonToken+ 26 | +RegularExpressionLiteral+ 27 | +TemplateSubstitutionTail+ 28 | 29 | InputElementTemplateTail := 30 | +WhiteSpace+ 31 | +LineTerminator+ 32 | +CommonToken+ 33 | +DivPunctuator+ 34 | +TemplateSubstitutionTail+ 35 | 36 | WhiteSpace := 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | LineTerminator := 47 | 48 | 49 | 50 | 51 | 52 | 53 | LineTerminatorSequence := 54 | 55 | 56 | 57 | 58 | 59 | 60 | CommonToken := 61 | +IdentifierName+ 62 | +Punctuator+ 63 | +NumericLiteral+ 64 | +StringLiteral+ 65 | +Template+ 66 | 67 | IdentifierName := 68 | +IdentifierStart+ 69 | +IdentifierName+ +IdentifierPart+ 70 | 71 | IdentifierStart := 72 | $ 73 | _ 74 | \ 75 | 76 | IdentifierPart := 77 | $ 78 | _ 79 | \ +UnicodeEscapeSequence+ 80 | 81 | 82 | 83 | ReservedWord := 84 | +Keyword+ 85 | +FutureReservedWord+ 86 | +NullLIteral+ 87 | +BooleanLiteral+ 88 | 89 | Keyword := 90 | break 91 | case 92 | catch 93 | class 94 | const 95 | continue 96 | debugger 97 | default 98 | delete 99 | do 100 | else 101 | export 102 | extends 103 | finally 104 | for 105 | function 106 | if 107 | import 108 | in 109 | instanceof 110 | new 111 | return 112 | super 113 | switch 114 | this 115 | throw 116 | try 117 | typeof 118 | var 119 | void 120 | while 121 | with 122 | yield 123 | 124 | FutureReservedWord := 125 | enum 126 | await 127 | implements 128 | interface 129 | package 130 | private 131 | protected 132 | public 133 | 134 | Punctuator := 135 | { 136 | } 137 | ( 138 | ) 139 | [ 140 | ] 141 | . 142 | ; 143 | , 144 | < 145 | > 146 | <= 147 | >= 148 | == 149 | != 150 | === 151 | !== 152 | + 153 | - 154 | * 155 | % 156 | ++ 157 | -- 158 | << 159 | >> 160 | >>> 161 | & 162 | | 163 | ^ 164 | ! 165 | ~ 166 | && 167 | ? 168 | : 169 | = 170 | += 171 | -= 172 | *= 173 | %= 174 | <<= 175 | >>= 176 | >>>= 177 | &= 178 | |= 179 | ^= 180 | => 181 | 182 | DivPunctuator := 183 | / 184 | /= 185 | 186 | RightBracePunctuator := 187 | } 188 | 189 | NullLiteral := 190 | null 191 | 192 | BooleanLiteral := 193 | true 194 | false 195 | 196 | NumbericLiteral := 197 | +DecimalLiteral+ 198 | +BinaryLiteral+ 199 | +OctalIntegerLiteral+ 200 | +HexIntegerLiteral+ 201 | 202 | DecimalLiteral := 203 | +DecimalIntegerLiteral.+DecimalDigits+ 204 | .+DecimalDigits+ 205 | +DecimalIntegerLiteral+ 206 | 207 | DecimalIntegerLiteral := 208 | 0 209 | +NonZeroDigit+ 210 | +DecimalDigits+ 211 | 212 | DecimalDigits := 213 | +DecimalDigit+ 214 | 215 | DecimalDigit := 216 | 0 217 | 1 218 | 2 219 | 3 220 | 4 221 | 5 222 | 6 223 | 7 224 | 8 225 | 9 226 | 227 | NonZeroDigit := 228 | 1 229 | 2 230 | 3 231 | 4 232 | 5 233 | 6 234 | 7 235 | 8 236 | 9 237 | 238 | ExponentPart := 239 | +ExponentIndicator SignedInteger+ 240 | 241 | ExponentIndicator := 242 | e 243 | E 244 | 245 | SignedInteger := 246 | +DecimalDigits+ 247 | ++DecimalDigits+ 248 | -+DecimalDigits+ 249 | 250 | BinaryIntegerLiteral := 251 | 0b+BinaryDigits+ 252 | 0B+BinaryDigits+ 253 | 254 | 255 | BinaryDigits := 256 | +BinaryDigit+ 257 | +BinaryDigits+ 258 | 259 | BinaryDigit := 260 | 0 261 | 1 262 | 263 | OctalIntegerLiteral := 264 | 0o +OctalDigits+ 265 | 0O +OctalDigits+ 266 | 267 | OctalDigits := 268 | +OctalDigits+ 269 | +OctalDigit+ 270 | 271 | OctalDigit := 272 | 0 273 | 1 274 | 2 275 | 3 276 | 4 277 | 5 278 | 6 279 | 7 280 | 281 | HexIntegerLiteral := 282 | 0xHexDigits 283 | 0XHexDigits 284 | 285 | 286 | HexDigits := 287 | +HexDigit+ 288 | +HexDigits+ 289 | 290 | HexDigit := 291 | 0 292 | 1 293 | 2 294 | 3 295 | 4 296 | 5 297 | 6 298 | 7 299 | 8 300 | 9 301 | a 302 | b 303 | c 304 | d 305 | e 306 | f 307 | A 308 | B 309 | C 310 | D 311 | E 312 | F 313 | 314 | 315 | StringLiteral := 316 | ' ' +DoubleStringCharacters+ ' ' 317 | ' ' +SingleStringCharacters+ ' ' 318 | 319 | DoubleStringCharacters := 320 | +DoubleStringCharacter+ 321 | +DoubleStringCharacters+ 322 | 323 | SingleStringCharacters := 324 | +SingleStringCharacter+ 325 | +SingleStringCharacters+ 326 | 327 | DoubleStringCharacter := 328 | \+EscapeSequence+ 329 | +LineContinuation+ 330 | 331 | SingleStringCharacter := 332 | \+EscapeSequence+ 333 | +LineContinuation+ 334 | 335 | LineContinuation := 336 | \+LineTerminatorSequence+ 337 | 338 | 339 | EscapeSequence := 340 | +CharacterEscapeSequence+ 341 | +HexEscapeSequence+ 342 | +UnicodeEscapeSequence+ 343 | 344 | CharacterEscapeSequence := 345 | +SingleEscapeCharacter+ 346 | +NonEscapeCharacter+ 347 | 348 | SingleEscapeCharacter := 349 | ' 350 | ' ' 351 | \ 352 | b 353 | f 354 | n 355 | r 356 | t 357 | v 358 | 359 | NonEscapeCharacter := 360 | #x0012 361 | #x0015 362 | #x2028 363 | #x2029 364 | 365 | EscapeCharacter := 366 | +SingleEscapeCharacter+ 367 | +DecimalDigit+ 368 | x 369 | u 370 | 371 | HexEscapeSequence := 372 | x +HexDigit+ +HexDigit+ 373 | 374 | 375 | UnicodeEscapeSequence := 376 | u +Hex4Digits+ 377 | u[+HexDigits+, +HexDigits+] 378 | 379 | 380 | Hex4Digits := 381 | +HexDigit+ +HexDigit+ +HexDigit+ +HexDigit+ 382 | 383 | RegularExpressionLiteral := 384 | / RegularExpressionBody / RegularExpressionFlags 385 | 386 | 387 | RegularExpressionBody := 388 | +RegularExpressionFirstChar +RegularExpressionChars+ 389 | 390 | RegularExpressionChars := 391 | +RegularExpressionChars+ 392 | +RegularExpressionChar+ 393 | 394 | RegularExpressionFirstChar := 395 | \ / []| RegularExpressionBackslashSequence+ 396 | +RegularExpressionClass+ 397 | 398 | RegularExpressionChar := 399 | [^ 400 | #x0012 401 | #x0015 402 | #x2028 403 | #x2029 404 | \ 405 | / 406 | [] 407 | +RegularExpressionBackslashSequence+ 408 | +RegularExpressionClass+ 409 | 410 | RegularExpressionBackslashSequence := 411 | \ +RegularExpressionNonTerminator+ 412 | 413 | 414 | RegularExpressionNonTerminator := 415 | [^ 416 | #x0012 417 | #x0015 418 | #x2028 419 | #x2029 420 | ] 421 | 422 | RegularExpressionClass := 423 | [ +RegularExpressionClassChars+ ] 424 | 425 | 426 | RegularExpressionClassChars := 427 | +RegularExpressionClassChars+ 428 | +RegularExpressionClassChar+ 429 | 430 | RegularExpressionClassChar := 431 | [^ 432 | \ 433 | #x0012 434 | #x0015 435 | #x2028 436 | #x2029 437 | #x005D 438 | ]+ 439 | +RegularExpressionBackslashSequence+ 440 | 441 | RegularExpressionFlags := 442 | +RegularExpressionFlags+ 443 | +IdentifierPart+ 444 | 445 | Template := 446 | +NoSubstitutionTemplate+ 447 | +TemplateHead+ 448 | 449 | NoSubstitutionTemplate := 450 | `+TemplateCharacters+` 451 | 452 | TemplateHead := 453 | `+TemplateCharacters+ ${ 454 | 455 | TemplateSubstitutionTail := 456 | +TemplateMiddle+ 457 | +TemplateTail+ 458 | 459 | TemplateMiddle := 460 | } +TemplateCharacters+ ${ 461 | 462 | TemplateTail := 463 | } +TemplateCharacters+ ` 464 | 465 | TemplateCharacters := 466 | +TemplateCharacter+ 467 | +TemplateCharacters+ 468 | 469 | TemplateCharacter := 470 | $ [^{] 471 | \ +EscapeSequence+ 472 | +LineContinuation+ 473 | +LineTerminatorSequence+ 474 | [^ ` \ $ #x0012 #x0015 #x2028 #x2029] 475 | 476 | IdentifierReference := 477 | +Identifier+ 478 | yield 479 | 480 | BindingIdentifier := 481 | +Identifier+ 482 | yield 483 | 484 | LabelIdentifier := 485 | +Identifier+ 486 | yield 487 | 488 | Identifier := 489 | +IdentifierName+ 490 | 491 | PrimaryExpression := 492 | this 493 | IdentifierReference 494 | Literal 495 | ArrayLiteral 496 | ObjectLiteral 497 | FunctionExpression 498 | ClassExpression 499 | GeneratorExpression 500 | RegularExpressionLiteral 501 | 502 | TemplateLIteral 503 | +CoverParenthesizedExpressionAndArrowParameterList+ 504 | 505 | CoverParenthesizedExpressionAndArrowParameterList := 506 | ( +Expression+ ) 507 | ( ) 508 | ( ... +BindingIdentifier+ ) 509 | ( +Expression+ , ... +BindingIdentifier+ ) 510 | 511 | 512 | ParenthesizedExpression := 513 | (+Expression+) 514 | 515 | 516 | Literal := 517 | +NullLiteral+ 518 | +BooleanLiteral+ 519 | +NumbericLiteral+ 520 | +StringLiteral+ 521 | 522 | ArrayLiteral := 523 | [ +Elision+ ] 524 | [ +ElementList+ ] 525 | [ +ElementList+ , +Elision+ ] 526 | 527 | 528 | ElementList := 529 | +Elision+ +AssignmentExpression+ 530 | +Elision+ +SpreadElement+ 531 | +ElementList+, Elision, +AssignmentExpression+ 532 | +ElementLIst+, 533 | +Elision+ 534 | +SpreadElement+ 535 | 536 | Elision := 537 | , 538 | Elision , 539 | 540 | 541 | SpreadElement := 542 | ... +AssignmentExpression+ 543 | 544 | 545 | ObjectLiteral := 546 | { } 547 | { +PropertyDefinitionList+} 548 | { +PropertyDefinitionList+ , } 549 | 550 | 551 | PropertyDefinitionList := 552 | +PropertyDefinition+ 553 | +PropertyDefinitionList+,+PropertyDefinition+ 554 | 555 | PropertyDefinition := 556 | +IdentifierReference+ 557 | +CoverInitializedName+ 558 | +PropertyName+ : +AssignmentExpression+ 559 | +MethodDefinition+ 560 | 561 | PropertyName := 562 | +LiteralPropertyName+ 563 | +ComputedPropertyName+ 564 | 565 | LiteralPropertyName := 566 | +IdentifierName+ 567 | +StringLiteral+ 568 | +NumericLiteral+ 569 | 570 | ComputedPropertyName := 571 | [ +AssignmentExpression+ ] 572 | 573 | 574 | CoverInitializedName := 575 | +IdentifierReference+ +Initializer+ 576 | 577 | Initializer := 578 | = +AssignmentExpression+ 579 | 580 | 581 | TemplateLiteral := 582 | +NoSubstitutionTemplate+ 583 | +TemplateHead+ +Expression+ +TemplateSpans+ 584 | 585 | TemplateSpans := 586 | +TemplateTail+ 587 | +TemplateMiddleList+ +TemplateTail+ 588 | 589 | TemplateMiddleList := 590 | +TemplateMiddle+ +Expression+ 591 | +TemplateMiddleList+ +TemplateMiddle+ +Expression+ 592 | 593 | MemberExpression := 594 | +PrimaryExpression+ 595 | +MemberExpression [ Expression ]+ 596 | +MemberExpression+.+IdentifierName+ 597 | +MemberExpression+ +TemplateLiteral+ 598 | +SuperProperty+ 599 | +MetaProperty+ 600 | new +MemberExpression+ +Arguments+ 601 | 602 | SuperProperty := 603 | super [ +Expression+ ] 604 | super . IdentifierName 605 | 606 | 607 | MetaProperty := 608 | +NewTarget+ 609 | 610 | NewTarget := 611 | new.target 612 | 613 | 614 | NewExpression := 615 | +MemberExpression+ 616 | new +NewExpression+ 617 | 618 | CallExpression := 619 | +MemberExpression+ +Arguments+ 620 | +SuperCall+ 621 | +CallExpression+ +Arguments+ 622 | +CallExpression+ [ +Expression+ ]+ 623 | +CallExpression+.+IdentifierName+ 624 | +CallExpression+ +TemplateLiteral+ 625 | 626 | SuperCall := 627 | super +Arguments+ 628 | 629 | 630 | Arguments := 631 | ( ) 632 | ( ArgumentList ) 633 | 634 | 635 | ArgumentList := 636 | +AssignmentExpression+ 637 | + ... +AssignmentExpression+ 638 | +ArgumentList+ , +AssignmentExpression+ 639 | +ArugmentList+ , ... +AssignmentExpression+ 640 | 641 | LeftHandSideExpression := 642 | +NewExpression+ 643 | +CallExpression+ 644 | 645 | PostfixExpression := 646 | +LeftHandSideExpression+ 647 | +LeftHandSideExpression+ 648 | +LeftHandSideExpression+ 649 | 650 | UnaryExpression := 651 | +PostfixExpression+ 652 | delete +UnaryExpression+ 653 | void +UnaryExpression+ 654 | typeof +UnaryExpression+ 655 | +UnaryExpression+ 656 | -- UnaryExpression 657 | + +UnaryExpression+ 658 | - +UnaryExpression+ 659 | ~ +UnaryExpression+ 660 | ! +UnaryExpression+ 661 | 662 | MultiplicativeExpression := 663 | +UnaryExpression+ 664 | +MultiplicativeExpression+ 665 | +MultiplicativeOperator+ 666 | +UnaryExpression+ 667 | 668 | MultiplicativeOperator := 669 | * 670 | / 671 | % 672 | 673 | AdditiveExpression := 674 | +MultiplicativeExpression+ 675 | +AdditiveExpression+ + +MultiplicativeExpression+ 676 | +AdditiveExpression+ - +MultiplicativeExpression+ 677 | 678 | ShiftExpression := 679 | +AdditiveExpression+ 680 | +ShiftExpression+ << +AdditiveExpression+ 681 | +ShiftExpression+ >> +AdditiveExpression+ 682 | +ShiftExpression+ >>> +AdditiveExpression+ 683 | 684 | RelationalExpression := 685 | +ShiftExpression+ 686 | +RelationalExpression+ < +ShiftExpression+ 687 | +RelationalExpression+ > +ShiftExpression+ 688 | +RelationalExpression+ <= +ShiftExpression+ 689 | +RelationalExpression+ >= +ShiftExpression+ 690 | +RelationalExpression+ instanceof +ShiftExpression+ 691 | +RelationalExpression+ in +ShiftExpression+ 692 | 693 | EqualityExpression := 694 | +RelationalExpression+ 695 | +EqualityExpression+ == +RelationalExpression+ 696 | +EqualityExpression+ != +RelationalExpression+ 697 | +EqualityExpression+ === +RelationalExpression+ 698 | +EqualityExpression+ !== +RelationalExpression+ 699 | 700 | BitwiseANDExpression := 701 | +RelationalExpression+ 702 | +BitwiseANDExpression+ & +RelationalExpression+ 703 | 704 | BitwiseXORExpression := 705 | +BitwiseANDExpression+ 706 | +BitwiseXORExpression+ ^ +BitwiseANDExpression+ 707 | 708 | BitwiseORExpression := 709 | +BitwiseXORExpression+ 710 | +BitwiseORExpression+ 711 | +BitwiseXORExpression+ 712 | +ConditionalExpression+ 713 | +LogicalORExpression+ 714 | +LogicalORExpression+ ? +AssignmentExpression+ : +AssignmentExpression+ 715 | 716 | AssignmentExpression := 717 | +ConditionalExpression+ 718 | +YieldExpression+= 719 | +ArrowFunction+ 720 | +LeftHandSideExpression+ = +AssignmentExpression+ 721 | +LeftHandSideExpression+ +AssignmentOperator+ +AssignmentExpression+ 722 | 723 | AssignmentOperator := 724 | *= 725 | /= 726 | %= 727 | += 728 | -= 729 | <<= 730 | >>= 731 | >>>= 732 | &= 733 | ^= 734 | |= 735 | 736 | 737 | Expression := 738 | +AssignmentExpression+ 739 | +Expression+ +AssignmentExpression+ 740 | 741 | Statement := 742 | +BlockStatement+ 743 | +VariableStatement+ 744 | +EmptyStatement+ 745 | +ExpressionStatement+ 746 | +IfStatement+ 747 | +BreakableStatement+ 748 | +ContinueStatement+ 749 | +BreakStatement+ 750 | +ReturnStatement+ 751 | +WithStatement+ 752 | +LabelledStatement+ 753 | +ThrowStatement+ 754 | +TryStatement+ 755 | +DebuggerStatement+ 756 | 757 | Declaration := 758 | +HoistableDeclaration+ 759 | +ClassDeclaration+ 760 | +LexicalDeclaration+ 761 | 762 | HoistableDeclaration := 763 | +FunctionDeclaration+ 764 | +GeneratorDeclaration+ 765 | 766 | BreakableStatement := 767 | +IterationStatement+ 768 | +SwitchStatement+ 769 | 770 | BlockStatement := 771 | +Block+ 772 | 773 | Block := 774 | {+StatementList+} 775 | 776 | 777 | StatementList := 778 | +StatementListItem+ 779 | +StatementList+ +StatementListItem+ 780 | 781 | StatementListItem := 782 | +Statement+ 783 | +Declaration+ 784 | 785 | LexicalDeclaration := 786 | +LetOrConst+ +BindingList+ 787 | 788 | LetOrConst := 789 | let 790 | const 791 | 792 | BindingList := 793 | +LexicalBinding+ 794 | +BindingList+ , +LexicalBinding+ 795 | 796 | LexicalBinding := 797 | +BindingIdentifier+ +Initializer?+ 798 | +BindingPattern+ +Initializer+ 799 | 800 | VariableStatement := 801 | var +VariableDeclarationList+ 802 | 803 | VariableDeclarationList := 804 | +VariableDeclaration+ 805 | +VariableDeclarationList+ , +VariableDeclaration+ 806 | 807 | VariableDeclaration := 808 | +BindingIdentifier +Initializer+ 809 | +BindingPattern+ +Initializer+ 810 | 811 | BindingPattern := 812 | +ObjectBindingPattern+ 813 | +ArrayBindingPattern+ 814 | 815 | ObjectBindingPattern := 816 | { } 817 | { +BindingPropertyList+ } 818 | { +BindingPropertyList+ , } 819 | 820 | 821 | ArrayBindingPattern := 822 | [ +BindingRestElement+ ] 823 | [ +BindingElementList+ ] 824 | [ +BindingElementList+ , +Elision+, +BindingRestElement+ ] 825 | 826 | BindingPropertyList := 827 | +BindingProperty+ 828 | +BindingPropertyList+ 829 | +BindingProperty+ 830 | 831 | BindingElementList := 832 | +BindingElisionElement+ 833 | +BindingElementList+ , +BindingElisionElement+ 834 | 835 | BindingElisionElement := 836 | +Elision+ 837 | +BindingElement+ 838 | 839 | BindingProperty := 840 | +SingleNameBinding+ 841 | +PropertyName+ : +BindingElement+ 842 | 843 | BindingElement := 844 | +SingleNameBinding+ 845 | +BindingPattern+ 846 | +Initializer+ 847 | 848 | SingleNameBinding := 849 | +BindingIdentifier+ 850 | +Initializer+ 851 | 852 | BindingRestElement := 853 | ... +BindingIdentifier+ 854 | 855 | 856 | EmptyStatement := 857 | ; 858 | 859 | 860 | ExpressionStatement := 861 | +Expression+; 862 | 863 | IfStatement := 864 | if ( +Expression+ ) +Statement+ else +statement+ 865 | if ( +Expression+ ) +Statement+ 866 | 867 | IterationStatement := 868 | do +Statement+ while ( +Expression+ ); 869 | while ( +Expression+ ) +Statement+ 870 | for ( +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 871 | for ( var +VariableDeclarationList+ ; +Expression+ ; +Expression+ ) +Statement+ 872 | for ( +LexicalDeclaration+ +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 873 | for ( +LeftHandSideExpression+ in +Expression+ ) +Statement+ 874 | for ( var +ForBinding+ in +Expression+ ) +Statement+ 875 | for ( +ForDeclaration+ in +Expression+ ) +Statement+ 876 | for ( +LeftHandSideExpression+ of +AssignmentExpression+ ) +Statement+ 877 | for ( var +ForBinding+ of +AssignmentExpression+ ) +Statement+ 878 | for ( +LexicalDeclaration+ +Expression+ of +AssignmentExpression+ ) +Statement+ 879 | 880 | ForDeclaration := 881 | +LetOrConst+ +ForBinding+ 882 | 883 | ForBinding := 884 | +BindingIdentifier+ 885 | +BindingPattern+ 886 | 887 | ContinueStatement := 888 | continue; 889 | continue +LabelIdentifier+; 890 | 891 | BreakStatement := 892 | break; 893 | break +LabelIdentifier+ ; 894 | 895 | ReturnStatement := 896 | return ; 897 | return +Expression+ ; 898 | 899 | WithStatement := 900 | with ( +Expression+ ) +Statement+ 901 | 902 | SwitchStatement := 903 | switch ( +Expression+ ) +CaseBlock+ 904 | 905 | 906 | CaseBlock := 907 | { +CaseClauses+ } 908 | { +CaseClauses+ +DefaultClause+ +CaseClauses+ } 909 | 910 | CaseClauses := 911 | +CaseClause+ 912 | +CaseClauses+ +CaseClause+ 913 | 914 | CaseClause := 915 | case +Expression+ : +StatementList+ 916 | 917 | DefaultClause := 918 | default : +StatementList+ 919 | 920 | LabelledStatement := 921 | +LabelIdentifier+ : +LabelledItem+ 922 | 923 | LabelledItem := 924 | +Statement+ 925 | +FunctionDeclaration+ 926 | 927 | ThrowStatement := 928 | throw +Expression+ ; 929 | 930 | TryStatement := 931 | try +Block+ +Catch+ 932 | try +Block+ +Finally+ 933 | try +Block+ +Catch+ finally 934 | 935 | Catch := 936 | catch ( +CatchParameter+ ) +Block+ 937 | 938 | Finally := 939 | finally +Block+ 940 | 941 | CatchParameter := 942 | +BindingIdentifier+ 943 | +BindingPattern+ 944 | 945 | DebuggerStatement := 946 | debugger; 947 | 948 | FunctionDeclaration := 949 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 950 | 951 | FunctionExpression := 952 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 953 | 954 | StrictFormalParameters := 955 | +FormalParameters+ 956 | 957 | FormalParameters := 958 | +FormalParameterList+ 959 | 960 | FormalParameterList := 961 | +FunctionRestParameter+ 962 | +FormalsList+ 963 | +FormalsList+ , +FormalParameter+ 964 | 965 | FormalsList := 966 | +FormalParameter+ 967 | +FormalsList+ , +FormalParameter+ 968 | 969 | FunctionRestParameter := 970 | +BindingRestElement+ 971 | 972 | FormalParameter := 973 | +BindingElement+ 974 | 975 | FunctionBody := 976 | +FunctionStatementList+ 977 | 978 | FunctionStatementList := 979 | +StatementList?+ 980 | 981 | ArrowFunction := 982 | +ArrowParameters+ => +ConciseBody+ 983 | 984 | ArrowParameters := 985 | +BindingIdentifier+ 986 | +CoverParenthesizedExpressionAndArrowParameterList+ 987 | 988 | ConciseBody := 989 | +AssignmentExpression+ 990 | +{+FunctionBody+}+ 991 | 992 | ArrowFormalParameters := 993 | ( +StrictFormalParameters+ ) 994 | 995 | MethodDefinition := 996 | +PropertyName+ ( +StrictFormalParameters+ ) { +FunctionBody+ } 997 | 998 | GeneratorMethod := 999 | get +PropertyName+ ( ){ +FunctionBody+ } 1000 | set +PropertyName+ ( +PropertySetParameterList+ ) { +FunctionBody+ } 1001 | 1002 | PropertySetParameterList := 1003 | +FormalParameter+ 1004 | 1005 | GeneratorMethod := 1006 | * +PropertyName+ ( +StrictFormalParameters+ ){ GeneratorBody} 1007 | 1008 | 1009 | GeneratorDeclaration := 1010 | function * BindingIdentifier ( FormalParameters ){ GeneratorBody } 1011 | function * ( +FormalParameters+ ) { +GeneratorBody+ } 1012 | 1013 | GeneratorExpression := 1014 | function * +BindingIdentifier+ ( +FormalParameters+ ) { +GeneratorBody+ } 1015 | 1016 | 1017 | GeneratorBody := 1018 | +FunctionBody+ 1019 | 1020 | YieldExpression := 1021 | yield 1022 | yield +AssignmentExpression+ 1023 | yield +AssignmentExpression+ 1024 | 1025 | ClassDeclaration := 1026 | class +BindingIdentifier+ +ClassTail+ 1027 | class +ClassTail+ 1028 | 1029 | ClassExpression := 1030 | class +BindingIdentifier+ +ClassTail+ 1031 | 1032 | ClassTail := 1033 | +ClassHeritage+ { +ClassBody+ } 1034 | 1035 | ClassHeritage := 1036 | extends +LeftHandSideExpression+ 1037 | 1038 | ClassBody := 1039 | +ClassElementList+ 1040 | 1041 | ClassElementList := 1042 | +ClassElement+ 1043 | classElementList 1044 | +ClassElement+ 1045 | 1046 | ClassElement := 1047 | +MethodDefinition+ 1048 | static +MethodDefinition+; 1049 | 1050 | script := 1051 | +ScriptBody+ 1052 | 1053 | ScriptBody := 1054 | +StatementList+ 1055 | 1056 | Module := 1057 | +ModuleBody?+ 1058 | 1059 | ModuleBody := 1060 | +ModuleItemList+ 1061 | 1062 | ModuleItemList := 1063 | +ModuleItem+ 1064 | +ModuleItemList+ +ModuleItem+ 1065 | 1066 | ModuleItem := 1067 | +ImportDeclaration+ 1068 | +ExportDeclaration+ 1069 | +StatementListItem+ 1070 | 1071 | ImportDeclaration := 1072 | import +ImportClause+ +FromClause+; 1073 | import +ModuleSpecifier+ ; 1074 | 1075 | ImportClause := 1076 | +ImportedDefaultBinding+ 1077 | +NameSpaceImport+ 1078 | +NamedImports+ 1079 | +ImportedDefaultBinding+ ,+NameSpaceImport+ 1080 | +ImportedDefaultBinding+ ,+NamedImports+ 1081 | 1082 | ImportedDefaultBinding := 1083 | +ImportedBinding+ 1084 | 1085 | NameSpaceImport := 1086 | * "as" +ImportedBinding+ 1087 | 1088 | NamedImports := 1089 | { } 1090 | 1091 | FromClause := 1092 | from +ModuleSpecifier+ 1093 | 1094 | ImportsList := 1095 | +ImportSpecifier+ 1096 | +ImportsList+ , +ImportSpecifier+ 1097 | 1098 | ImportSpecifier := 1099 | +ImportedBinding+ 1100 | +IdentifierName+ as +ImportedBinding+ 1101 | 1102 | ModuleSpecifier := 1103 | +StringLiteral+ 1104 | 1105 | ImportedBinding := 1106 | +BindingIdentifier+ 1107 | 1108 | ExportDeclaration := 1109 | export * +FromClause+ ; 1110 | export +ExportClause+ +FromClause+ ; 1111 | export +ExportClause+ ; 1112 | export +VariableStatement+; 1113 | export +Declaration+ 1114 | export default +HoistableDeclaration+ 1115 | export default +ClassDeclaration+ 1116 | export default +AssignmentExpression+ ; 1117 | 1118 | ExportClause := 1119 | { } 1120 | { +ExportList+ } 1121 | { +ExportList+ } 1122 | 1123 | ExportList := 1124 | +ExportSpecifier+ 1125 | +ExportsList+ , +ExportSpecifier+ 1126 | 1127 | ExportSpecifier := 1128 | +IdentifierName+ 1129 | +IdentifierName+ as +IdentifierName+ 1130 | 1131 | StringNumericLiteral := 1132 | +StrWhiteSpace+ 1133 | +StrWhiteSpace+ +StrNumericLiteral+ +StrWhiteSpace+ 1134 | 1135 | StrWhiteSpace := 1136 | +StrWhiteSpaceChar+ +StrWhiteSpace+ 1137 | 1138 | StrWhiteSpaceChar := 1139 | +WhiteSpace+ 1140 | +LineTerminator+ 1141 | 1142 | StrNumericLiteral := 1143 | +StrDecimalLiteral+ 1144 | +BinaryIntegerLiteral+ 1145 | +OctalIntegerLiteral+ 1146 | +HexIntegerLiteral+ 1147 | 1148 | StrDecimalLiteral := 1149 | +StrUnsignedDecimalLiteral+ 1150 | ++StrUnsignedDecimalLiteral+ 1151 | -+StrUnsignedDecimalLiteral+ 1152 | 1153 | StrUnsignedDecimalLiteral := 1154 | +Infinity+ 1155 | +DecimalDigits+.+DecimalDigits+ 1156 | .DecimalDigits 1157 | DecimalDigits 1158 | 1159 | uri := 1160 | +uriCharacters+ 1161 | 1162 | uriCharacters := 1163 | +uriCharacter+ +uriCharacters+ 1164 | 1165 | uriCharacter := 1166 | +uriReserved+ 1167 | +uriUnescaped+ 1168 | +uriEscaped+ 1169 | 1170 | uriReserved := 1171 | + 1172 | ; 1173 | / 1174 | ? 1175 | : 1176 | @ 1177 | & 1178 | = 1179 | + 1180 | $ 1181 | , 1182 | + 1183 | 1184 | uriUnescaped := 1185 | +uriAlpha+ 1186 | +DecimalDigit+ 1187 | +uriMark+ 1188 | 1189 | uriEscaped := 1190 | % +HexDigit+ +HexDigit+ 1191 | 1192 | 1193 | uriAlpha := 1194 | a 1195 | b 1196 | c 1197 | d 1198 | e 1199 | f 1200 | g 1201 | h 1202 | i 1203 | j 1204 | k 1205 | l 1206 | m 1207 | n 1208 | o 1209 | p 1210 | q 1211 | r 1212 | s 1213 | t 1214 | u 1215 | v 1216 | w 1217 | x 1218 | y 1219 | z 1220 | A 1221 | B 1222 | C 1223 | D 1224 | E 1225 | F 1226 | G 1227 | H 1228 | I 1229 | J 1230 | K 1231 | L 1232 | M 1233 | N 1234 | O 1235 | P 1236 | Q 1237 | R 1238 | S 1239 | T 1240 | U 1241 | V 1242 | W 1243 | X 1244 | Y 1245 | Z 1246 | 1247 | uriMark := 1248 | - 1249 | _ 1250 | . 1251 | ! 1252 | ~ 1253 | * 1254 | ' 1255 | ( 1256 | ) 1257 | ] 1258 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/grammar.dg: -------------------------------------------------------------------------------- 1 | %section% := value 2 | 3 | array := 4 | [+arrayvalues+] 5 | 6 | arrayvalues := 7 | %repeat%(+common:int+, ", ") 8 | %repeat%(+common:short_int+, ", ") 9 | %repeat%(+common:intoverflow+, ", ") 10 | %repeat%(+common:byte+, ", ") 11 | 12 | string := 13 | '+common:text+' 14 | 15 | math := 16 | +common:int+ +common:sign+ +common:int+ 17 | +string+ +common:sign+ +common:int+ 18 | +string+ +common:sign+ +string+ 19 | +array+ +common:sign+ +array+ 20 | 21 | negative_number := 22 | -+common:positive_integer+ 23 | 24 | intArgs := 25 | null 26 | undefined 27 | NaN 28 | +negative_number+ 29 | +common:integer+ 30 | +common:bad_number+ 31 | +common:decimal_number+ 32 | +common:scientific_number+ 33 | +common:hex+ 34 | +common:byte+ 35 | 36 | builtinMath := 37 | Math.PI 38 | Math.E 39 | Math.LN10 40 | Math.LN2 41 | Math.LOG10E 42 | MATH.LOG2E 43 | MATH.SQRT1_2 44 | Math.abs( %repeat%(+intArgs+, ", ") ) 45 | Math.acos( %repeat%(+intArgs+, ", ") ) 46 | Math.acosh( %repeat%(+intArgs+, ", ") ) 47 | Math.asin( %repeat%(+intArgs+, ", ") ) 48 | Math.asinh( %repeat%(+intArgs+, ", ") ) 49 | Math.atan( %repeat%(+intArgs+, ", ") ) 50 | Math.atan2( %repeat%(+intArgs+, ", ") ) 51 | Math.atanh( %repeat%(+intArgs+, ", ") ) 52 | Math.cbrt( %repeat%(+intArgs+, ", ") ) 53 | Math.ceil( %repeat%(+intArgs+, ", ") ) 54 | Math.clz32( %repeat%(+intArgs+, ", ") ) 55 | Math.constructor( %repeat%(+intArgs+, ", ") ) 56 | Math.cos( %repeat%(+intArgs+, ", ") ) 57 | Math.cosh( %repeat%(+intArgs+, ", ") ) 58 | Math.exp( %repeat%(+intArgs+, ", ") ) 59 | Math.expm1( %repeat%(+intArgs+, ", ") ) 60 | Math.floor( %repeat%(+intArgs+, ", ") ) 61 | Math.fround( %repeat%(+intArgs+, ", ") ) 62 | Math.hasOwnProperty( %repeat%(+intArgs+, ", ") ) 63 | Math.hypot( %repeat%(+intArgs+, ", ") ) 64 | Math.imul( %repeat%(+intArgs+, ", ") ) 65 | Math.isPrototypeOf( %repeat%(+intArgs+, ", ") ) 66 | Math.log( %repeat%(+intArgs+, ", ") ) 67 | Math.log10( %repeat%(+intArgs+, ", ") ) 68 | Math.log1p( %repeat%(+intArgs+, ", ") ) 69 | Math.log2( %repeat%(+intArgs+, ", ") ) 70 | Math.max( %repeat%(+intArgs+, ", ") ) 71 | Math.min( %repeat%(+intArgs+, ", ") ) 72 | Math.pow( %repeat%(+intArgs+, ", ") ) 73 | Math.propertyIsEnumerable( %repeat%(+intArgs+, ", ") ) 74 | Math.random( %repeat%(+intArgs+, ", ") ) 75 | Math.round( %repeat%(+intArgs+, ", ") ) 76 | Math.sign( %repeat%(+intArgs+, ", ") ) 77 | Math.sin( %repeat%(+intArgs+, ", ") ) 78 | Math.sinh( %repeat%(+intArgs+, ", ") ) 79 | Math.sqrt( %repeat%(+intArgs+, ", ") ) 80 | Math.tan( %repeat%(+intArgs+, ", ") ) 81 | Math.tanh( %repeat%(+intArgs+, ", ") ) 82 | Math.toLocaleString( %repeat%(+intArgs+, ", ") ) 83 | Math.toSource( %repeat%(+intArgs+, ", ") ) 84 | Math.toString( %repeat%(+intArgs+, ", ") ) 85 | Math.trunc( %repeat%(+intArgs+, ", ") ) 86 | Math.valueOf( %repeat%(+intArgs+, ", ") ) 87 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/lex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | jabooby = 0 3 | max_jab = 979879 4 | with open("es6.ebnf.1", "r") as gramm: 5 | for line in gramm: 6 | line = [x.strip(" ") for x in line.split("::=")] 7 | line = " := | " .join(line) 8 | line = line.strip().replace(" | ", "\n\t") 9 | print(line.split(":=")[0] + " := ", end = "") 10 | for i in range(1, len(line.split(":="))): 11 | new = line.split(":=")[i] 12 | if new[2] == "\"": 13 | print(new) 14 | else: 15 | new2 = new[2:] 16 | for i in new2.split("\n\t"): 17 | print("\n\t" + "+" + i + "+", end = "") 18 | #print("\n\t" + "+" + new[2:].s + "+") 19 | print() 20 | print() 21 | jabooby += 1 22 | if jabooby == max_jab: 23 | break 24 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/old.dg: -------------------------------------------------------------------------------- 1 | InputElementRegExpOrTemplateTail := 2 | +LineTerminator+ 3 | +CommonToken+ 4 | +RegularExpressionLiteral+ 5 | +TemplateSubstitutionTail+ 6 | 7 | InputElementTemplateTail := 8 | +LineTerminator+ 9 | +CommonToken+ 10 | +DivPunctuator+ 11 | +TemplateSubstitutionTail+ 12 | 13 | CommonToken := 14 | +IdentifierName+ 15 | +Punctuator+ 16 | +common:int+ 17 | +StringLiteral+ 18 | +Template+ 19 | 20 | IdentifierName := 21 | +IdentifierStart+ 22 | +IdentifierName+ +IdentifierPart+ 23 | 24 | IdentifierStart := 25 | $ 26 | _ 27 | \ 28 | 29 | IdentifierPart := 30 | $ 31 | _ 32 | \ +UnicodeEscapeSequence+ 33 | 34 | ReservedWord := 35 | +Keyword+ 36 | +FutureReservedWord+ 37 | +NullLiteral+ 38 | +BooleanLiteral+ 39 | 40 | Keyword := 41 | break 42 | case 43 | catch 44 | class 45 | const 46 | continue 47 | debugger 48 | default 49 | delete 50 | do 51 | else 52 | export 53 | extends 54 | finally 55 | for 56 | function 57 | if 58 | import 59 | in 60 | instanceof 61 | new 62 | return 63 | super 64 | switch 65 | this 66 | throw 67 | try 68 | typeof 69 | var 70 | void 71 | while 72 | with 73 | yield 74 | 75 | FutureReservedWord := 76 | enum 77 | await 78 | implements 79 | interface 80 | package 81 | private 82 | protected 83 | public 84 | 85 | Punctuator := 86 | { 87 | } 88 | ( 89 | ) 90 | [ 91 | ] 92 | . 93 | ; 94 | , 95 | < 96 | > 97 | <= 98 | >= 99 | == 100 | != 101 | === 102 | !== 103 | + 104 | - 105 | * 106 | % 107 | ++ 108 | -- 109 | << 110 | >> 111 | >>> 112 | & 113 | | 114 | ^ 115 | ! 116 | ~ 117 | && 118 | ? 119 | : 120 | = 121 | += 122 | -= 123 | *= 124 | %= 125 | <<= 126 | >>= 127 | >>>= 128 | &= 129 | |= 130 | ^= 131 | => 132 | 133 | DivPunctuator := 134 | / 135 | /= 136 | 137 | RightBracePunctuator := 138 | } 139 | 140 | NullLiteral := 141 | null 142 | 143 | BooleanLiteral := 144 | true 145 | false 146 | 147 | BinaryLiteral := 148 | 0 149 | 1 150 | 151 | NumericLiteral := 152 | +DecimalLiteral+ 153 | +BinaryLiteral+ 154 | +OctalIntegerLiteral+ 155 | +HexIntegerLiteral+ 156 | 157 | DecimalLiteral := 158 | +DecimalIntegerLiteral.+DecimalDigits+ 159 | .+DecimalDigits+ 160 | +DecimalIntegerLiteral+ 161 | 162 | DecimalIntegerLiteral := 163 | 0 164 | +NonZeroDigit+ 165 | +DecimalDigits+ 166 | 167 | DecimalDigits := 168 | +DecimalDigit+ 169 | 170 | DecimalDigit := 171 | 0 172 | 1 173 | 2 174 | 3 175 | 4 176 | 5 177 | 6 178 | 7 179 | 8 180 | 9 181 | 182 | NonZeroDigit := 183 | 1 184 | 2 185 | 3 186 | 4 187 | 5 188 | 6 189 | 7 190 | 8 191 | 9 192 | 193 | ExponentPart := 194 | +ExponentIndicator SignedInteger+ 195 | 196 | ExponentIndicator := 197 | e 198 | E 199 | 200 | SignedInteger := 201 | +DecimalDigits+ 202 | ++DecimalDigits+ 203 | -+DecimalDigits+ 204 | 205 | BinaryIntegerLiteral := 206 | 0b+BinaryDigits+ 207 | 0B+BinaryDigits+ 208 | 209 | 210 | BinaryDigits := 211 | +BinaryDigit+ 212 | 213 | BinaryDigit := 214 | 0 215 | 1 216 | 217 | OctalIntegerLiteral := 218 | 0o +OctalDigits+ 219 | 0O +OctalDigits+ 220 | 221 | OctalDigits := 222 | +OctalDigits+ 223 | +OctalDigit+ 224 | 225 | OctalDigit := 226 | 0 227 | 1 228 | 2 229 | 3 230 | 4 231 | 5 232 | 6 233 | 7 234 | 235 | HexIntegerLiteral := 236 | 0xHexDigits 237 | 0XHexDigits 238 | 239 | 240 | HexDigits := 241 | +HexDigit+ 242 | 243 | HexDigit := 244 | 0 245 | 1 246 | 2 247 | 3 248 | 4 249 | 5 250 | 6 251 | 7 252 | 8 253 | 9 254 | a 255 | b 256 | c 257 | d 258 | e 259 | f 260 | A 261 | B 262 | C 263 | D 264 | E 265 | F 266 | 267 | 268 | StringLiteral := 269 | ' ' +DoubleStringCharacters+ ' ' 270 | ' ' +SingleStringCharacters+ ' ' 271 | 272 | DoubleStringCharacters := 273 | +DoubleStringCharacter+ 274 | +DoubleStringCharacters+ 275 | 276 | SingleStringCharacters := 277 | +SingleStringCharacter+ 278 | +SingleStringCharacters+ 279 | 280 | DoubleStringCharacter := 281 | \+EscapeSequence+ 282 | +LineContinuation+ 283 | 284 | SingleStringCharacter := 285 | \+EscapeSequence+ 286 | +LineContinuation+ 287 | 288 | EscapeSequence := 289 | +CharacterEscapeSequence+ 290 | +HexEscapeSequence+ 291 | +UnicodeEscapeSequence+ 292 | 293 | CharacterEscapeSequence := 294 | +SingleEscapeCharacter+ 295 | +NonEscapeCharacter+ 296 | 297 | SingleEscapeCharacter := 298 | ' 299 | ' ' 300 | \ 301 | b 302 | f 303 | n 304 | r 305 | t 306 | v 307 | 308 | NonEscapeCharacter := 309 | #x0012 310 | #x0015 311 | #x2028 312 | #x2029 313 | 314 | EscapeCharacter := 315 | +SingleEscapeCharacter+ 316 | +DecimalDigit+ 317 | x 318 | u 319 | 320 | HexEscapeSequence := 321 | x +HexDigit+ +HexDigit+ 322 | 323 | 324 | UnicodeEscapeSequence := 325 | u +Hex4Digits+ 326 | u[+HexDigits+, +HexDigits+] 327 | 328 | 329 | Hex4Digits := 330 | +HexDigit+ +HexDigit+ +HexDigit+ +HexDigit+ 331 | 332 | RegularExpressionLiteral := 333 | / RegularExpressionBody / RegularExpressionFlags 334 | 335 | 336 | RegularExpressionBody := 337 | +RegularExpressionFirstChar +RegularExpressionChars+ 338 | 339 | RegularExpressionChars := 340 | +RegularExpressionChar+ 341 | 342 | RegularExpressionFirstChar := 343 | \ / []| RegularExpressionBackslashSequence+ 344 | +RegularExpressionClass+ 345 | 346 | RegularExpressionChar := 347 | [^ 348 | \ 349 | / 350 | [] 351 | +RegularExpressionBackslashSequence+ 352 | +RegularExpressionClass+ 353 | 354 | RegularExpressionBackslashSequence := 355 | \ +RegularExpressionNonTerminator+ 356 | 357 | 358 | RegularExpressionNonTerminator := 359 | #x0012 360 | #x2029 361 | 362 | RegularExpressionClass := 363 | [ +RegularExpressionClassChars+ ] 364 | 365 | 366 | RegularExpressionClassChars := 367 | +RegularExpressionClassChars+ 368 | +RegularExpressionClassChar+ 369 | 370 | RegularExpressionClassChar := 371 | +RegularExpressionBackslashSequence+ 372 | 373 | RegularExpressionFlags := 374 | +IdentifierPart+ 375 | 376 | Template := 377 | +NoSubstitutionTemplate+ 378 | +TemplateHead+ 379 | 380 | NoSubstitutionTemplate := 381 | `+TemplateCharacters+` 382 | 383 | TemplateHead := 384 | `+TemplateCharacters+ ${ 385 | 386 | TemplateSubstitutionTail := 387 | +TemplateMiddle+ 388 | +TemplateTail+ 389 | 390 | TemplateMiddle := 391 | } +TemplateCharacters+ ${ 392 | 393 | TemplateTail := 394 | } +TemplateCharacters+ ` 395 | 396 | TemplateCharacters := 397 | +TemplateCharacter+ 398 | +TemplateCharacters+ 399 | 400 | IdentifierReference := 401 | +Identifier+ 402 | yield 403 | 404 | BindingIdentifier := 405 | +Identifier+ 406 | yield 407 | 408 | LabelIdentifier := 409 | +Identifier+ 410 | yield 411 | 412 | Identifier := 413 | +IdentifierName+ 414 | 415 | PrimaryExpression := 416 | this 417 | IdentifierReference 418 | Literal 419 | ArrayLiteral 420 | ObjectLiteral 421 | FunctionExpression 422 | ClassExpression 423 | GeneratorExpression 424 | RegularExpressionLiteral 425 | 426 | CoverParenthesizedExpressionAndArrowParameterList := 427 | ( +Expression+ ) 428 | ( ) 429 | ( ... +BindingIdentifier+ ) 430 | ( +Expression+ , ... +BindingIdentifier+ ) 431 | 432 | 433 | ParenthesizedExpression := 434 | (+Expression+) 435 | 436 | 437 | Literal := 438 | +NullLiteral+ 439 | +BooleanLiteral+ 440 | +NumericLiteral+ 441 | +StringLiteral+ 442 | 443 | ArrayLiteral := 444 | [ +Elision+ ] 445 | [ +ElementList+ ] 446 | [ +ElementList+ , +Elision+ ] 447 | 448 | 449 | ElementList := 450 | +Elision+ +AssignmentExpression+ 451 | +Elision+ +SpreadElement+ 452 | +Elision+ 453 | +SpreadElement+ 454 | 455 | Elision := 456 | , 457 | 458 | 459 | SpreadElement := 460 | ... +AssignmentExpression+ 461 | 462 | 463 | ObjectLiteral := 464 | { } 465 | { +PropertyDefinitionList+} 466 | { +PropertyDefinitionList+ , } 467 | 468 | 469 | PropertyDefinitionList := 470 | +PropertyDefinition+ 471 | +PropertyDefinitionList+,+PropertyDefinition+ 472 | 473 | PropertyDefinition := 474 | +IdentifierReference+ 475 | +CoverInitializedName+ 476 | +PropertyName+ : +AssignmentExpression+ 477 | +MethodDefinition+ 478 | 479 | PropertyName := 480 | +LiteralPropertyName+ 481 | +ComputedPropertyName+ 482 | 483 | LiteralPropertyName := 484 | +IdentifierName+ 485 | +StringLiteral+ 486 | +NumericLiteral+ 487 | 488 | ComputedPropertyName := 489 | [ +AssignmentExpression+ ] 490 | 491 | 492 | CoverInitializedName := 493 | +IdentifierReference+ +Initializer+ 494 | 495 | Initializer := 496 | = +AssignmentExpression+ 497 | 498 | 499 | TemplateLiteral := 500 | +NoSubstitutionTemplate+ 501 | +TemplateHead+ +Expression+ +TemplateSpans+ 502 | 503 | TemplateSpans := 504 | +TemplateTail+ 505 | +TemplateMiddleList+ +TemplateTail+ 506 | 507 | TemplateMiddleList := 508 | +TemplateMiddle+ +Expression+ 509 | 510 | MemberExpression := 511 | +PrimaryExpression+ 512 | +SuperProperty+ 513 | +MetaProperty+ 514 | 515 | SuperProperty := 516 | super [ +Expression+ ] 517 | super . +IdentifierName+ 518 | 519 | 520 | MetaProperty := 521 | +NewTarget+ 522 | 523 | NewTarget := 524 | new.target 525 | 526 | 527 | NewExpression := 528 | new +MemberExpression+ 529 | 530 | CallExpression := 531 | +MemberExpression+ +Arguments+ 532 | +SuperCall+ 533 | 534 | SuperCall := 535 | super +Arguments+ 536 | 537 | 538 | Arguments := 539 | ( ) 540 | ( ArgumentList ) 541 | 542 | 543 | ArgumentList := 544 | +AssignmentExpression+ 545 | 546 | LeftHandSideExpression := 547 | +NewExpression+ 548 | +CallExpression+ 549 | 550 | PostfixExpression := 551 | +LeftHandSideExpression+ 552 | 553 | UnaryExpression := 554 | +PostfixExpression+ 555 | 556 | MultiplicativeExpression := 557 | +UnaryExpression+ 558 | +MultiplicativeOperator+ 559 | 560 | MultiplicativeOperator := 561 | * 562 | / 563 | % 564 | 565 | AdditiveExpression := 566 | +MultiplicativeExpression+ 567 | +AdditiveExpression+ + +MultiplicativeExpression+ 568 | +AdditiveExpression+ - +MultiplicativeExpression+ 569 | 570 | ShiftExpression := 571 | +AdditiveExpression+ 572 | +ShiftExpression+ << +AdditiveExpression+ 573 | +ShiftExpression+ >> +AdditiveExpression+ 574 | +ShiftExpression+ >>> +AdditiveExpression+ 575 | 576 | RelationalExpression := 577 | +ShiftExpression+ 578 | +RelationalExpression+ < +ShiftExpression+ 579 | +RelationalExpression+ > +ShiftExpression+ 580 | +RelationalExpression+ <= +ShiftExpression+ 581 | +RelationalExpression+ >= +ShiftExpression+ 582 | +RelationalExpression+ instanceof +ShiftExpression+ 583 | +RelationalExpression+ in +ShiftExpression+ 584 | 585 | EqualityExpression := 586 | +RelationalExpression+ 587 | +EqualityExpression+ == +RelationalExpression+ 588 | +EqualityExpression+ != +RelationalExpression+ 589 | +EqualityExpression+ === +RelationalExpression+ 590 | +EqualityExpression+ !== +RelationalExpression+ 591 | 592 | BitwiseANDExpression := 593 | +RelationalExpression+ 594 | +BitwiseANDExpression+ & +RelationalExpression+ 595 | 596 | BitwiseXORExpression := 597 | +BitwiseANDExpression+ 598 | 599 | BitwiseORExpression := 600 | +BitwiseXORExpression+ 601 | +BitwiseXORExpression+ 602 | 603 | AssignmentExpression := 604 | +YieldExpression+= 605 | +ArrowFunction+ 606 | +LeftHandSideExpression+ = +AssignmentExpression+ 607 | +LeftHandSideExpression+ +AssignmentOperator+ +AssignmentExpression+ 608 | 609 | AssignmentOperator := 610 | *= 611 | /= 612 | %= 613 | += 614 | -= 615 | <<= 616 | >>= 617 | >>>= 618 | &= 619 | ^= 620 | |= 621 | 622 | 623 | Expression := 624 | +AssignmentExpression+ 625 | 626 | Statement := 627 | +BlockStatement+ 628 | +VariableStatement+ 629 | +EmptyStatement+ 630 | +ExpressionStatement+ 631 | +IfStatement+ 632 | +BreakableStatement+ 633 | +ContinueStatement+ 634 | +BreakStatement+ 635 | +ReturnStatement+ 636 | +WithStatement+ 637 | +LabelledStatement+ 638 | +ThrowStatement+ 639 | +TryStatement+ 640 | +DebuggerStatement+ 641 | 642 | Declaration := 643 | +HoistableDeclaration+ 644 | +ClassDeclaration+ 645 | +LexicalDeclaration+ 646 | 647 | HoistableDeclaration := 648 | +FunctionDeclaration+ 649 | +GeneratorDeclaration+ 650 | 651 | BreakableStatement := 652 | +IterationStatement+ 653 | +SwitchStatement+ 654 | 655 | BlockStatement := 656 | +Block+ 657 | 658 | Block := 659 | { +StatementList+ } 660 | 661 | StatementListItem := 662 | +Statement+ 663 | +Declaration+ 664 | 665 | StatementList := 666 | +StatementListItem+ 667 | 668 | LexicalDeclaration := 669 | +LetOrConst+ +BindingList+ 670 | 671 | LetOrConst := 672 | let 673 | const 674 | 675 | BindingList := 676 | +LexicalBinding+ 677 | 678 | LexicalBinding := 679 | +BindingIdentifier+ +Initializer?+ 680 | +BindingPattern+ +Initializer+ 681 | 682 | VariableStatement := 683 | var +VariableDeclarationList+ 684 | 685 | VariableDeclarationList := 686 | +VariableDeclaration+ 687 | 688 | VariableDeclaration := 689 | +BindingIdentifier +Initializer+ 690 | +BindingPattern+ +Initializer+ 691 | 692 | BindingPattern := 693 | +ObjectBindingPattern+ 694 | +ArrayBindingPattern+ 695 | 696 | ObjectBindingPattern := 697 | { } 698 | { +BindingPropertyList+ } 699 | { +BindingPropertyList+ , } 700 | 701 | 702 | ArrayBindingPattern := 703 | [ +BindingRestElement+ ] 704 | [ +BindingElementList+ ] 705 | [ +BindingElementList+ , +Elision+, +BindingRestElement+ ] 706 | 707 | BindingPropertyList := 708 | +BindingProperty+ 709 | 710 | BindingElementList := 711 | +BindingElisionElement+ 712 | 713 | BindingElisionElement := 714 | +Elision+ 715 | +BindingElement+ 716 | 717 | BindingProperty := 718 | +SingleNameBinding+ 719 | +PropertyName+ : +BindingElement+ 720 | 721 | BindingElement := 722 | +SingleNameBinding+ 723 | +BindingPattern+ 724 | +Initializer+ 725 | 726 | SingleNameBinding := 727 | +BindingIdentifier+ 728 | +Initializer+ 729 | 730 | BindingRestElement := 731 | +BindingIdentifier+ 732 | 733 | 734 | EmptyStatement := 735 | ; 736 | 737 | 738 | ExpressionStatement := 739 | +Expression+; 740 | 741 | IfStatement := 742 | if ( +Expression+ ) +Statement+ else +Statement+ 743 | if ( +Expression+ ) +Statement+ 744 | 745 | IterationStatement := 746 | do +Statement+ while ( +Expression+ ); 747 | while ( +Expression+ ) +Statement+ 748 | for ( +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 749 | for ( var +VariableDeclarationList+ ; +Expression+ ; +Expression+ ) +Statement+ 750 | for ( +LexicalDeclaration+ +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 751 | for ( +LeftHandSideExpression+ in +Expression+ ) +Statement+ 752 | for ( var +ForBinding+ in +Expression+ ) +Statement+ 753 | for ( +ForDeclaration+ in +Expression+ ) +Statement+ 754 | for ( +LeftHandSideExpression+ of +AssignmentExpression+ ) +Statement+ 755 | for ( var +ForBinding+ of +AssignmentExpression+ ) +Statement+ 756 | for ( +LexicalDeclaration+ +Expression+ of +AssignmentExpression+ ) +Statement+ 757 | 758 | ForDeclaration := 759 | +LetOrConst+ +ForBinding+ 760 | 761 | ForBinding := 762 | +BindingIdentifier+ 763 | +BindingPattern+ 764 | 765 | ContinueStatement := 766 | continue; 767 | continue +LabelIdentifier+; 768 | 769 | BreakStatement := 770 | break; 771 | break +LabelIdentifier+ ; 772 | 773 | ReturnStatement := 774 | return ; 775 | return +Expression+ ; 776 | 777 | WithStatement := 778 | with ( +Expression+ ) +Statement+ 779 | 780 | SwitchStatement := 781 | switch ( +Expression+ ) +CaseBlock+ 782 | 783 | CaseBlock := 784 | { +CaseClauses+ } 785 | { +CaseClauses+ +DefaultClause+ +CaseClauses+ } 786 | 787 | CaseClauses := 788 | +CaseClause+ 789 | 790 | CaseClause := 791 | case +Expression+ : +StatementList+ 792 | 793 | DefaultClause := 794 | default : +StatementList+ 795 | 796 | LabelledStatement := 797 | +LabelIdentifier+ : +LabelledItem+ 798 | 799 | LabelledItem := 800 | +Statement+ 801 | +FunctionDeclaration+ 802 | 803 | ThrowStatement := 804 | throw +Expression+ ; 805 | 806 | TryStatement := 807 | try +Block+ +Catch+ 808 | try +Block+ +Finally+ 809 | try +Block+ +Catch+ finally 810 | 811 | Catch := 812 | catch ( +CatchParameter+ ) +Block+ 813 | 814 | Finally := 815 | finally +Block+ 816 | 817 | CatchParameter := 818 | +BindingIdentifier+ 819 | +BindingPattern+ 820 | 821 | DebuggerStatement := 822 | debugger; 823 | 824 | FunctionDeclaration := 825 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 826 | 827 | FunctionExpression := 828 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 829 | 830 | StrictFormalParameters := 831 | +FormalParameters+ 832 | 833 | FormalParameters := 834 | +FormalParameterList+ 835 | 836 | FormalParameterList := 837 | +FunctionRestParameter+ 838 | +FormalsList+ 839 | +FormalsList+ , +FormalParameter+ 840 | 841 | FormalsList := 842 | +FormalParameter+ 843 | +FormalsList+ , +FormalParameter+ 844 | 845 | FunctionRestParameter := 846 | +BindingRestElement+ 847 | 848 | FormalParameter := 849 | +BindingElement+ 850 | 851 | FunctionBody := 852 | +FunctionStatementList+ 853 | 854 | FunctionStatementList := 855 | +StatementList+ 856 | 857 | ArrowFunction := 858 | +ArrowParameters+ => +ConciseBody+ 859 | 860 | ArrowParameters := 861 | +BindingIdentifier+ 862 | +CoverParenthesizedExpressionAndArrowParameterList+ 863 | 864 | ConciseBody := 865 | +AssignmentExpression+ 866 | +{+FunctionBody+}+ 867 | 868 | ArrowFormalParameters := 869 | ( +StrictFormalParameters+ ) 870 | 871 | MethodDefinition := 872 | +PropertyName+ ( +StrictFormalParameters+ ) { +FunctionBody+ } 873 | 874 | GeneratorMethod := 875 | get +PropertyName+ ( ){ +FunctionBody+ } 876 | set +PropertyName+ ( +PropertySetParameterList+ ) { +FunctionBody+ } 877 | 878 | PropertySetParameterList := 879 | +FormalParameter+ 880 | 881 | GeneratorDeclaration := 882 | function * BindingIdentifier ( FormalParameters ){ GeneratorBody } 883 | function * ( +FormalParameters+ ) { +GeneratorBody+ } 884 | 885 | GeneratorExpression := 886 | function * +BindingIdentifier+ ( +FormalParameters+ ) { +GeneratorBody+ } 887 | 888 | GeneratorBody := 889 | +FunctionBody+ 890 | 891 | YieldExpression := 892 | yield 893 | yield +AssignmentExpression+ 894 | yield +AssignmentExpression+ 895 | 896 | ClassDeclaration := 897 | class +BindingIdentifier+ +ClassTail+ 898 | class +ClassTail+ 899 | 900 | ClassExpression := 901 | class +BindingIdentifier+ +ClassTail+ 902 | 903 | ClassTail := 904 | +ClassHeritage+ { +ClassBody+ } 905 | 906 | ClassHeritage := 907 | extends +LeftHandSideExpression+ 908 | 909 | ClassBody := 910 | +ClassElementList+ 911 | 912 | ClassElementList := 913 | +ClassElement+ 914 | 915 | ClassElement := 916 | +MethodDefinition+ 917 | static +MethodDefinition+; 918 | 919 | script := 920 | +ScriptBody+ 921 | 922 | ScriptBody := 923 | +StatementList+ 924 | 925 | Module := 926 | +ModuleBody?+ 927 | 928 | ModuleBody := 929 | +ModuleItemList+ 930 | 931 | ModuleItemList := 932 | +ModuleItem+ 933 | 934 | ModuleItem := 935 | +ImportDeclaration+ 936 | +ExportDeclaration+ 937 | +StatementListItem+ 938 | 939 | ImportDeclaration := 940 | import +ImportClause+ +FromClause+; 941 | import +ModuleSpecifier+ ; 942 | 943 | ImportClause := 944 | +ImportedDefaultBinding+ 945 | +NameSpaceImport+ 946 | +NamedImports+ 947 | +ImportedDefaultBinding+ ,+NameSpaceImport+ 948 | +ImportedDefaultBinding+ ,+NamedImports+ 949 | 950 | ImportedDefaultBinding := 951 | +ImportedBinding+ 952 | 953 | NameSpaceImport := 954 | * "as" +ImportedBinding+ 955 | 956 | NamedImports := 957 | { } 958 | 959 | FromClause := 960 | from +ModuleSpecifier+ 961 | 962 | ImportsList := 963 | +ImportSpecifier+ 964 | 965 | ImportSpecifier := 966 | +ImportedBinding+ 967 | +IdentifierName+ as +ImportedBinding+ 968 | 969 | ModuleSpecifier := 970 | +StringLiteral+ 971 | 972 | ImportedBinding := 973 | +BindingIdentifier+ 974 | 975 | ExportDeclaration := 976 | export * +FromClause+ ; 977 | export +ExportClause+ +FromClause+ ; 978 | export +ExportClause+ ; 979 | export +VariableStatement+; 980 | export +Declaration+ 981 | export default +HoistableDeclaration+ 982 | export default +ClassDeclaration+ 983 | export default +AssignmentExpression+ ; 984 | 985 | ExportClause := 986 | { } 987 | { +ExportList+ } 988 | 989 | ExportList := 990 | +ExportSpecifier+ 991 | 992 | ExportSpecifier := 993 | +IdentifierName+ 994 | +IdentifierName+ as +IdentifierName+ 995 | 996 | StringNumericLiteral := 997 | +StrWhiteSpace+ 998 | +StrWhiteSpace+ +StrNumericLiteral+ +StrWhiteSpace+ 999 | 1000 | StrWhiteSpace := 1001 | +StrWhiteSpaceChar+ +StrWhiteSpace+ 1002 | 1003 | StrWhiteSpaceChar := 1004 | +WhiteSpace+ 1005 | +LineTerminator+ 1006 | 1007 | StrNumericLiteral := 1008 | +StrDecimalLiteral+ 1009 | +BinaryIntegerLiteral+ 1010 | +OctalIntegerLiteral+ 1011 | +HexIntegerLiteral+ 1012 | 1013 | StrDecimalLiteral := 1014 | +StrUnsignedDecimalLiteral+ 1015 | ++StrUnsignedDecimalLiteral+ 1016 | -+StrUnsignedDecimalLiteral+ 1017 | 1018 | StrUnsignedDecimalLiteral := 1019 | +DecimalDigits+.+DecimalDigits+ 1020 | .+DecimalDigits+ 1021 | +DecimalDigits+ 1022 | 1023 | uri := 1024 | +uriCharacters+ 1025 | 1026 | uriCharacters := 1027 | +uriCharacter+ 1028 | 1029 | uriCharacter := 1030 | +uriReserved+ 1031 | +uriUnescaped+ 1032 | +uriEscaped+ 1033 | 1034 | uriReserved := 1035 | + 1036 | ; 1037 | / 1038 | ? 1039 | : 1040 | @ 1041 | & 1042 | = 1043 | + 1044 | $ 1045 | , 1046 | + 1047 | 1048 | uriUnescaped := 1049 | +uriAlpha+ 1050 | +DecimalDigit+ 1051 | +uriMark+ 1052 | 1053 | uriEscaped := 1054 | % +HexDigit+ +HexDigit+ 1055 | 1056 | 1057 | uriAlpha := 1058 | a 1059 | b 1060 | c 1061 | d 1062 | e 1063 | f 1064 | g 1065 | h 1066 | i 1067 | j 1068 | k 1069 | l 1070 | m 1071 | n 1072 | o 1073 | p 1074 | q 1075 | r 1076 | s 1077 | t 1078 | u 1079 | v 1080 | w 1081 | x 1082 | y 1083 | z 1084 | A 1085 | B 1086 | C 1087 | D 1088 | E 1089 | F 1090 | G 1091 | H 1092 | I 1093 | J 1094 | K 1095 | L 1096 | M 1097 | N 1098 | O 1099 | P 1100 | Q 1101 | R 1102 | S 1103 | T 1104 | U 1105 | V 1106 | W 1107 | X 1108 | Y 1109 | Z 1110 | 1111 | uriMark := 1112 | - 1113 | _ 1114 | . 1115 | ! 1116 | ~ 1117 | * 1118 | ' 1119 | ( 1120 | ) 1121 | ] 1122 | 1123 | builtinMath := 1124 | Math.PI 1125 | Math.E 1126 | Math.LN2 1127 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/old_values.dg: -------------------------------------------------------------------------------- 1 | Grammer := 2 | +Statement+ 3 | 4 | SourceCharacter := 5 | x000000 6 | x10FFFF 7 | 8 | InputElementDiv := 9 | +WhiteSpace+ 10 | +LineTerminator+ 11 | +CommonToken+ 12 | +DivPunctuator+ 13 | +RightBracePunctuator+ 14 | 15 | InputElementRegExp := 16 | +WhiteSpace+ 17 | +LineTerminator+ 18 | +CommonToken+ 19 | +RightBracePunctuator+ 20 | +RegularExpressionLiteral+ 21 | 22 | InputElementRegExpOrTemplateTail := 23 | +WhiteSpace+ 24 | +LineTerminator+ 25 | +CommonToken+ 26 | +RegularExpressionLiteral+ 27 | +TemplateSubstitutionTail+ 28 | 29 | InputElementTemplateTail := 30 | +WhiteSpace+ 31 | +LineTerminator+ 32 | +CommonToken+ 33 | +DivPunctuator+ 34 | +TemplateSubstitutionTail+ 35 | 36 | WhiteSpace := 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | LineTerminator := 47 | 48 | 49 | 50 | 51 | 52 | 53 | LineTerminatorSequence := 54 | 55 | 56 | 57 | 58 | 59 | 60 | CommonToken := 61 | +IdentifierName+ 62 | +Punctuator+ 63 | +common:int+ 64 | +StringLiteral+ 65 | +Template+ 66 | 67 | IdentifierName := 68 | +IdentifierStart+ 69 | +IdentifierName+ +IdentifierPart+ 70 | 71 | IdentifierStart := 72 | $ 73 | _ 74 | \ 75 | 76 | IdentifierPart := 77 | $ 78 | _ 79 | \ +UnicodeEscapeSequence+ 80 | 81 | 82 | 83 | ReservedWord := 84 | +Keyword+ 85 | +FutureReservedWord+ 86 | +NullLiteral+ 87 | +BooleanLiteral+ 88 | 89 | Keyword := 90 | break 91 | case 92 | catch 93 | class 94 | const 95 | continue 96 | debugger 97 | default 98 | delete 99 | do 100 | else 101 | export 102 | extends 103 | finally 104 | for 105 | function 106 | if 107 | import 108 | in 109 | instanceof 110 | new 111 | return 112 | super 113 | switch 114 | this 115 | throw 116 | try 117 | typeof 118 | var 119 | void 120 | while 121 | with 122 | yield 123 | 124 | FutureReservedWord := 125 | enum 126 | await 127 | implements 128 | interface 129 | package 130 | private 131 | protected 132 | public 133 | 134 | Punctuator := 135 | { 136 | } 137 | ( 138 | ) 139 | [ 140 | ] 141 | . 142 | ; 143 | , 144 | < 145 | > 146 | <= 147 | >= 148 | == 149 | != 150 | === 151 | !== 152 | + 153 | - 154 | * 155 | % 156 | ++ 157 | -- 158 | << 159 | >> 160 | >>> 161 | & 162 | | 163 | ^ 164 | ! 165 | ~ 166 | && 167 | ? 168 | : 169 | = 170 | += 171 | -= 172 | *= 173 | %= 174 | <<= 175 | >>= 176 | >>>= 177 | &= 178 | |= 179 | ^= 180 | => 181 | 182 | DivPunctuator := 183 | / 184 | /= 185 | 186 | RightBracePunctuator := 187 | } 188 | 189 | NullLiteral := 190 | null 191 | 192 | BooleanLiteral := 193 | true 194 | false 195 | 196 | BinaryLiteral := 197 | 0 198 | 1 199 | 200 | NumericLiteral := 201 | +DecimalLiteral+ 202 | +BinaryLiteral+ 203 | +OctalIntegerLiteral+ 204 | +HexIntegerLiteral+ 205 | 206 | DecimalLiteral := 207 | +DecimalIntegerLiteral.+DecimalDigits+ 208 | .+DecimalDigits+ 209 | +DecimalIntegerLiteral+ 210 | 211 | DecimalIntegerLiteral := 212 | 0 213 | +NonZeroDigit+ 214 | +DecimalDigits+ 215 | 216 | DecimalDigits := 217 | +DecimalDigit+ 218 | 219 | DecimalDigit := 220 | 0 221 | 1 222 | 2 223 | 3 224 | 4 225 | 5 226 | 6 227 | 7 228 | 8 229 | 9 230 | 231 | NonZeroDigit := 232 | 1 233 | 2 234 | 3 235 | 4 236 | 5 237 | 6 238 | 7 239 | 8 240 | 9 241 | 242 | ExponentPart := 243 | +ExponentIndicator SignedInteger+ 244 | 245 | ExponentIndicator := 246 | e 247 | E 248 | 249 | SignedInteger := 250 | +DecimalDigits+ 251 | ++DecimalDigits+ 252 | -+DecimalDigits+ 253 | 254 | BinaryIntegerLiteral := 255 | 0b+BinaryDigits+ 256 | 0B+BinaryDigits+ 257 | 258 | 259 | BinaryDigits := 260 | +BinaryDigit+ 261 | 262 | BinaryDigit := 263 | 0 264 | 1 265 | 266 | OctalIntegerLiteral := 267 | 0o +OctalDigits+ 268 | 0O +OctalDigits+ 269 | 270 | OctalDigits := 271 | +OctalDigits+ 272 | +OctalDigit+ 273 | 274 | OctalDigit := 275 | 0 276 | 1 277 | 2 278 | 3 279 | 4 280 | 5 281 | 6 282 | 7 283 | 284 | HexIntegerLiteral := 285 | 0xHexDigits 286 | 0XHexDigits 287 | 288 | 289 | HexDigits := 290 | +HexDigit+ 291 | 292 | HexDigit := 293 | 0 294 | 1 295 | 2 296 | 3 297 | 4 298 | 5 299 | 6 300 | 7 301 | 8 302 | 9 303 | a 304 | b 305 | c 306 | d 307 | e 308 | f 309 | A 310 | B 311 | C 312 | D 313 | E 314 | F 315 | 316 | 317 | StringLiteral := 318 | ' ' +DoubleStringCharacters+ ' ' 319 | ' ' +SingleStringCharacters+ ' ' 320 | 321 | DoubleStringCharacters := 322 | +DoubleStringCharacter+ 323 | +DoubleStringCharacters+ 324 | 325 | SingleStringCharacters := 326 | +SingleStringCharacter+ 327 | +SingleStringCharacters+ 328 | 329 | DoubleStringCharacter := 330 | \+EscapeSequence+ 331 | +LineContinuation+ 332 | 333 | SingleStringCharacter := 334 | \+EscapeSequence+ 335 | +LineContinuation+ 336 | 337 | LineContinuation := 338 | \+LineTerminatorSequence+ 339 | 340 | 341 | EscapeSequence := 342 | +CharacterEscapeSequence+ 343 | +HexEscapeSequence+ 344 | +UnicodeEscapeSequence+ 345 | 346 | CharacterEscapeSequence := 347 | +SingleEscapeCharacter+ 348 | +NonEscapeCharacter+ 349 | 350 | SingleEscapeCharacter := 351 | ' 352 | ' ' 353 | \ 354 | b 355 | f 356 | n 357 | r 358 | t 359 | v 360 | 361 | NonEscapeCharacter := 362 | #x0012 363 | #x0015 364 | #x2028 365 | #x2029 366 | 367 | EscapeCharacter := 368 | +SingleEscapeCharacter+ 369 | +DecimalDigit+ 370 | x 371 | u 372 | 373 | HexEscapeSequence := 374 | x +HexDigit+ +HexDigit+ 375 | 376 | 377 | UnicodeEscapeSequence := 378 | u +Hex4Digits+ 379 | u[+HexDigits+, +HexDigits+] 380 | 381 | 382 | Hex4Digits := 383 | +HexDigit+ +HexDigit+ +HexDigit+ +HexDigit+ 384 | 385 | RegularExpressionLiteral := 386 | / RegularExpressionBody / RegularExpressionFlags 387 | 388 | 389 | RegularExpressionBody := 390 | +RegularExpressionFirstChar +RegularExpressionChars+ 391 | 392 | RegularExpressionChars := 393 | +RegularExpressionChar+ 394 | 395 | RegularExpressionFirstChar := 396 | \ / []| RegularExpressionBackslashSequence+ 397 | +RegularExpressionClass+ 398 | 399 | RegularExpressionChar := 400 | [^ 401 | \ 402 | / 403 | [] 404 | +RegularExpressionBackslashSequence+ 405 | +RegularExpressionClass+ 406 | 407 | RegularExpressionBackslashSequence := 408 | \ +RegularExpressionNonTerminator+ 409 | 410 | 411 | RegularExpressionNonTerminator := 412 | #x0012 413 | #x2029 414 | 415 | RegularExpressionClass := 416 | [ +RegularExpressionClassChars+ ] 417 | 418 | 419 | RegularExpressionClassChars := 420 | +RegularExpressionClassChars+ 421 | +RegularExpressionClassChar+ 422 | 423 | RegularExpressionClassChar := 424 | +RegularExpressionBackslashSequence+ 425 | 426 | RegularExpressionFlags := 427 | +IdentifierPart+ 428 | 429 | Template := 430 | +NoSubstitutionTemplate+ 431 | +TemplateHead+ 432 | 433 | NoSubstitutionTemplate := 434 | `+TemplateCharacters+` 435 | 436 | TemplateHead := 437 | `+TemplateCharacters+ ${ 438 | 439 | TemplateSubstitutionTail := 440 | +TemplateMiddle+ 441 | +TemplateTail+ 442 | 443 | TemplateMiddle := 444 | } +TemplateCharacters+ ${ 445 | 446 | TemplateTail := 447 | } +TemplateCharacters+ ` 448 | 449 | TemplateCharacters := 450 | +TemplateCharacter+ 451 | +TemplateCharacters+ 452 | 453 | TemplateCharacter := 454 | +LineContinuation+ 455 | +LineTerminatorSequence+ 456 | 457 | IdentifierReference := 458 | +Identifier+ 459 | yield 460 | 461 | BindingIdentifier := 462 | +Identifier+ 463 | yield 464 | 465 | LabelIdentifier := 466 | +Identifier+ 467 | yield 468 | 469 | Identifier := 470 | +IdentifierName+ 471 | 472 | PrimaryExpression := 473 | this 474 | IdentifierReference 475 | Literal 476 | ArrayLiteral 477 | ObjectLiteral 478 | FunctionExpression 479 | ClassExpression 480 | GeneratorExpression 481 | RegularExpressionLiteral 482 | 483 | CoverParenthesizedExpressionAndArrowParameterList := 484 | ( +Expression+ ) 485 | ( ) 486 | ( ... +BindingIdentifier+ ) 487 | ( +Expression+ , ... +BindingIdentifier+ ) 488 | 489 | 490 | ParenthesizedExpression := 491 | (+Expression+) 492 | 493 | 494 | Literal := 495 | +NullLiteral+ 496 | +BooleanLiteral+ 497 | +NumericLiteral+ 498 | +StringLiteral+ 499 | 500 | ArrayLiteral := 501 | [ +Elision+ ] 502 | [ +ElementList+ ] 503 | [ +ElementList+ , +Elision+ ] 504 | 505 | 506 | ElementList := 507 | +Elision+ +AssignmentExpression+ 508 | +Elision+ +SpreadElement+ 509 | +Elision+ 510 | +SpreadElement+ 511 | 512 | Elision := 513 | , 514 | 515 | 516 | SpreadElement := 517 | ... +AssignmentExpression+ 518 | 519 | 520 | ObjectLiteral := 521 | { } 522 | { +PropertyDefinitionList+} 523 | { +PropertyDefinitionList+ , } 524 | 525 | 526 | PropertyDefinitionList := 527 | +PropertyDefinition+ 528 | +PropertyDefinitionList+,+PropertyDefinition+ 529 | 530 | PropertyDefinition := 531 | +IdentifierReference+ 532 | +CoverInitializedName+ 533 | +PropertyName+ : +AssignmentExpression+ 534 | +MethodDefinition+ 535 | 536 | PropertyName := 537 | +LiteralPropertyName+ 538 | +ComputedPropertyName+ 539 | 540 | LiteralPropertyName := 541 | +IdentifierName+ 542 | +StringLiteral+ 543 | +NumericLiteral+ 544 | 545 | ComputedPropertyName := 546 | [ +AssignmentExpression+ ] 547 | 548 | 549 | CoverInitializedName := 550 | +IdentifierReference+ +Initializer+ 551 | 552 | Initializer := 553 | = +AssignmentExpression+ 554 | 555 | 556 | TemplateLiteral := 557 | +NoSubstitutionTemplate+ 558 | +TemplateHead+ +Expression+ +TemplateSpans+ 559 | 560 | TemplateSpans := 561 | +TemplateTail+ 562 | +TemplateMiddleList+ +TemplateTail+ 563 | 564 | TemplateMiddleList := 565 | +TemplateMiddle+ +Expression+ 566 | 567 | MemberExpression := 568 | +PrimaryExpression+ 569 | +SuperProperty+ 570 | +MetaProperty+ 571 | 572 | SuperProperty := 573 | super [ +Expression+ ] 574 | super . +IdentifierName+ 575 | 576 | 577 | MetaProperty := 578 | +NewTarget+ 579 | 580 | NewTarget := 581 | new.target 582 | 583 | 584 | NewExpression := 585 | new +MemberExpression+ 586 | 587 | CallExpression := 588 | +MemberExpression+ +Arguments+ 589 | +SuperCall+ 590 | 591 | SuperCall := 592 | super +Arguments+ 593 | 594 | 595 | Arguments := 596 | ( ) 597 | ( ArgumentList ) 598 | 599 | 600 | ArgumentList := 601 | +AssignmentExpression+ 602 | 603 | LeftHandSideExpression := 604 | +NewExpression+ 605 | +CallExpression+ 606 | 607 | PostfixExpression := 608 | +LeftHandSideExpression+ 609 | 610 | UnaryExpression := 611 | +PostfixExpression+ 612 | 613 | MultiplicativeExpression := 614 | +UnaryExpression+ 615 | +MultiplicativeOperator+ 616 | 617 | MultiplicativeOperator := 618 | * 619 | / 620 | % 621 | 622 | AdditiveExpression := 623 | +MultiplicativeExpression+ 624 | +AdditiveExpression+ + +MultiplicativeExpression+ 625 | +AdditiveExpression+ - +MultiplicativeExpression+ 626 | 627 | ShiftExpression := 628 | +AdditiveExpression+ 629 | +ShiftExpression+ << +AdditiveExpression+ 630 | +ShiftExpression+ >> +AdditiveExpression+ 631 | +ShiftExpression+ >>> +AdditiveExpression+ 632 | 633 | RelationalExpression := 634 | +ShiftExpression+ 635 | +RelationalExpression+ < +ShiftExpression+ 636 | +RelationalExpression+ > +ShiftExpression+ 637 | +RelationalExpression+ <= +ShiftExpression+ 638 | +RelationalExpression+ >= +ShiftExpression+ 639 | +RelationalExpression+ instanceof +ShiftExpression+ 640 | +RelationalExpression+ in +ShiftExpression+ 641 | 642 | EqualityExpression := 643 | +RelationalExpression+ 644 | +EqualityExpression+ == +RelationalExpression+ 645 | +EqualityExpression+ != +RelationalExpression+ 646 | +EqualityExpression+ === +RelationalExpression+ 647 | +EqualityExpression+ !== +RelationalExpression+ 648 | 649 | BitwiseANDExpression := 650 | +RelationalExpression+ 651 | +BitwiseANDExpression+ & +RelationalExpression+ 652 | 653 | BitwiseXORExpression := 654 | +BitwiseANDExpression+ 655 | 656 | BitwiseORExpression := 657 | +BitwiseXORExpression+ 658 | +BitwiseXORExpression+ 659 | 660 | AssignmentExpression := 661 | +YieldExpression+= 662 | +ArrowFunction+ 663 | +LeftHandSideExpression+ = +AssignmentExpression+ 664 | +LeftHandSideExpression+ +AssignmentOperator+ +AssignmentExpression+ 665 | 666 | AssignmentOperator := 667 | *= 668 | /= 669 | %= 670 | += 671 | -= 672 | <<= 673 | >>= 674 | >>>= 675 | &= 676 | ^= 677 | |= 678 | 679 | 680 | Expression := 681 | +AssignmentExpression+ 682 | 683 | Statement := 684 | +BlockStatement+ 685 | +VariableStatement+ 686 | +EmptyStatement+ 687 | +ExpressionStatement+ 688 | +IfStatement+ 689 | +BreakableStatement+ 690 | +ContinueStatement+ 691 | +BreakStatement+ 692 | +ReturnStatement+ 693 | +WithStatement+ 694 | +LabelledStatement+ 695 | +ThrowStatement+ 696 | +TryStatement+ 697 | +DebuggerStatement+ 698 | 699 | Declaration := 700 | +HoistableDeclaration+ 701 | +ClassDeclaration+ 702 | +LexicalDeclaration+ 703 | 704 | HoistableDeclaration := 705 | +FunctionDeclaration+ 706 | +GeneratorDeclaration+ 707 | 708 | BreakableStatement := 709 | +IterationStatement+ 710 | +SwitchStatement+ 711 | 712 | BlockStatement := 713 | +Block+ 714 | 715 | Block := 716 | { +StatementList+ } 717 | 718 | StatementListItem := 719 | +Statement+ 720 | +Declaration+ 721 | 722 | StatementList := 723 | +StatementListItem+ 724 | 725 | LexicalDeclaration := 726 | +LetOrConst+ +BindingList+ 727 | 728 | LetOrConst := 729 | let 730 | const 731 | 732 | BindingList := 733 | +LexicalBinding+ 734 | 735 | LexicalBinding := 736 | +BindingIdentifier+ +Initializer?+ 737 | +BindingPattern+ +Initializer+ 738 | 739 | VariableStatement := 740 | var +VariableDeclarationList+ 741 | 742 | VariableDeclarationList := 743 | +VariableDeclaration+ 744 | 745 | VariableDeclaration := 746 | +BindingIdentifier +Initializer+ 747 | +BindingPattern+ +Initializer+ 748 | 749 | BindingPattern := 750 | +ObjectBindingPattern+ 751 | +ArrayBindingPattern+ 752 | 753 | ObjectBindingPattern := 754 | { } 755 | { +BindingPropertyList+ } 756 | { +BindingPropertyList+ , } 757 | 758 | 759 | ArrayBindingPattern := 760 | [ +BindingRestElement+ ] 761 | [ +BindingElementList+ ] 762 | [ +BindingElementList+ , +Elision+, +BindingRestElement+ ] 763 | 764 | BindingPropertyList := 765 | +BindingProperty+ 766 | 767 | BindingElementList := 768 | +BindingElisionElement+ 769 | 770 | BindingElisionElement := 771 | +Elision+ 772 | +BindingElement+ 773 | 774 | BindingProperty := 775 | +SingleNameBinding+ 776 | +PropertyName+ : +BindingElement+ 777 | 778 | BindingElement := 779 | +SingleNameBinding+ 780 | +BindingPattern+ 781 | +Initializer+ 782 | 783 | SingleNameBinding := 784 | +BindingIdentifier+ 785 | +Initializer+ 786 | 787 | BindingRestElement := 788 | +BindingIdentifier+ 789 | 790 | 791 | EmptyStatement := 792 | ; 793 | 794 | 795 | ExpressionStatement := 796 | +Expression+; 797 | 798 | IfStatement := 799 | if ( +Expression+ ) +Statement+ else +Statement+ 800 | if ( +Expression+ ) +Statement+ 801 | 802 | IterationStatement := 803 | do +Statement+ while ( +Expression+ ); 804 | while ( +Expression+ ) +Statement+ 805 | for ( +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 806 | for ( var +VariableDeclarationList+ ; +Expression+ ; +Expression+ ) +Statement+ 807 | for ( +LexicalDeclaration+ +Expression+ ; +Expression+ ; +Expression+ ) +Statement+ 808 | for ( +LeftHandSideExpression+ in +Expression+ ) +Statement+ 809 | for ( var +ForBinding+ in +Expression+ ) +Statement+ 810 | for ( +ForDeclaration+ in +Expression+ ) +Statement+ 811 | for ( +LeftHandSideExpression+ of +AssignmentExpression+ ) +Statement+ 812 | for ( var +ForBinding+ of +AssignmentExpression+ ) +Statement+ 813 | for ( +LexicalDeclaration+ +Expression+ of +AssignmentExpression+ ) +Statement+ 814 | 815 | ForDeclaration := 816 | +LetOrConst+ +ForBinding+ 817 | 818 | ForBinding := 819 | +BindingIdentifier+ 820 | +BindingPattern+ 821 | 822 | ContinueStatement := 823 | continue; 824 | continue +LabelIdentifier+; 825 | 826 | BreakStatement := 827 | break; 828 | break +LabelIdentifier+ ; 829 | 830 | ReturnStatement := 831 | return ; 832 | return +Expression+ ; 833 | 834 | WithStatement := 835 | with ( +Expression+ ) +Statement+ 836 | 837 | SwitchStatement := 838 | switch ( +Expression+ ) +CaseBlock+ 839 | 840 | CaseBlock := 841 | { +CaseClauses+ } 842 | { +CaseClauses+ +DefaultClause+ +CaseClauses+ } 843 | 844 | CaseClauses := 845 | +CaseClause+ 846 | 847 | CaseClause := 848 | case +Expression+ : +StatementList+ 849 | 850 | DefaultClause := 851 | default : +StatementList+ 852 | 853 | LabelledStatement := 854 | +LabelIdentifier+ : +LabelledItem+ 855 | 856 | LabelledItem := 857 | +Statement+ 858 | +FunctionDeclaration+ 859 | 860 | ThrowStatement := 861 | throw +Expression+ ; 862 | 863 | TryStatement := 864 | try +Block+ +Catch+ 865 | try +Block+ +Finally+ 866 | try +Block+ +Catch+ finally 867 | 868 | Catch := 869 | catch ( +CatchParameter+ ) +Block+ 870 | 871 | Finally := 872 | finally +Block+ 873 | 874 | CatchParameter := 875 | +BindingIdentifier+ 876 | +BindingPattern+ 877 | 878 | DebuggerStatement := 879 | debugger; 880 | 881 | FunctionDeclaration := 882 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 883 | 884 | FunctionExpression := 885 | function +BindingIdentifier+ ( +FormalParameters+ ) { +FunctionBody+ } 886 | 887 | StrictFormalParameters := 888 | +FormalParameters+ 889 | 890 | FormalParameters := 891 | +FormalParameterList+ 892 | 893 | FormalParameterList := 894 | +FunctionRestParameter+ 895 | +FormalsList+ 896 | +FormalsList+ , +FormalParameter+ 897 | 898 | FormalsList := 899 | +FormalParameter+ 900 | +FormalsList+ , +FormalParameter+ 901 | 902 | FunctionRestParameter := 903 | +BindingRestElement+ 904 | 905 | FormalParameter := 906 | +BindingElement+ 907 | 908 | FunctionBody := 909 | +FunctionStatementList+ 910 | 911 | FunctionStatementList := 912 | +StatementList+ 913 | 914 | ArrowFunction := 915 | +ArrowParameters+ => +ConciseBody+ 916 | 917 | ArrowParameters := 918 | +BindingIdentifier+ 919 | +CoverParenthesizedExpressionAndArrowParameterList+ 920 | 921 | ConciseBody := 922 | +AssignmentExpression+ 923 | +{+FunctionBody+}+ 924 | 925 | ArrowFormalParameters := 926 | ( +StrictFormalParameters+ ) 927 | 928 | MethodDefinition := 929 | +PropertyName+ ( +StrictFormalParameters+ ) { +FunctionBody+ } 930 | 931 | GeneratorMethod := 932 | get +PropertyName+ ( ){ +FunctionBody+ } 933 | set +PropertyName+ ( +PropertySetParameterList+ ) { +FunctionBody+ } 934 | 935 | PropertySetParameterList := 936 | +FormalParameter+ 937 | 938 | GeneratorDeclaration := 939 | function * BindingIdentifier ( FormalParameters ){ GeneratorBody } 940 | function * ( +FormalParameters+ ) { +GeneratorBody+ } 941 | 942 | GeneratorExpression := 943 | function * +BindingIdentifier+ ( +FormalParameters+ ) { +GeneratorBody+ } 944 | 945 | GeneratorBody := 946 | +FunctionBody+ 947 | 948 | YieldExpression := 949 | yield 950 | yield +AssignmentExpression+ 951 | yield +AssignmentExpression+ 952 | 953 | ClassDeclaration := 954 | class +BindingIdentifier+ +ClassTail+ 955 | class +ClassTail+ 956 | 957 | ClassExpression := 958 | class +BindingIdentifier+ +ClassTail+ 959 | 960 | ClassTail := 961 | +ClassHeritage+ { +ClassBody+ } 962 | 963 | ClassHeritage := 964 | extends +LeftHandSideExpression+ 965 | 966 | ClassBody := 967 | +ClassElementList+ 968 | 969 | ClassElementList := 970 | +ClassElement+ 971 | 972 | ClassElement := 973 | +MethodDefinition+ 974 | static +MethodDefinition+; 975 | 976 | script := 977 | +ScriptBody+ 978 | 979 | ScriptBody := 980 | +StatementList+ 981 | 982 | Module := 983 | +ModuleBody?+ 984 | 985 | ModuleBody := 986 | +ModuleItemList+ 987 | 988 | ModuleItemList := 989 | +ModuleItem+ 990 | 991 | ModuleItem := 992 | +ImportDeclaration+ 993 | +ExportDeclaration+ 994 | +StatementListItem+ 995 | 996 | ImportDeclaration := 997 | import +ImportClause+ +FromClause+; 998 | import +ModuleSpecifier+ ; 999 | 1000 | ImportClause := 1001 | +ImportedDefaultBinding+ 1002 | +NameSpaceImport+ 1003 | +NamedImports+ 1004 | +ImportedDefaultBinding+ ,+NameSpaceImport+ 1005 | +ImportedDefaultBinding+ ,+NamedImports+ 1006 | 1007 | ImportedDefaultBinding := 1008 | +ImportedBinding+ 1009 | 1010 | NameSpaceImport := 1011 | * "as" +ImportedBinding+ 1012 | 1013 | NamedImports := 1014 | { } 1015 | 1016 | FromClause := 1017 | from +ModuleSpecifier+ 1018 | 1019 | ImportsList := 1020 | +ImportSpecifier+ 1021 | 1022 | ImportSpecifier := 1023 | +ImportedBinding+ 1024 | +IdentifierName+ as +ImportedBinding+ 1025 | 1026 | ModuleSpecifier := 1027 | +StringLiteral+ 1028 | 1029 | ImportedBinding := 1030 | +BindingIdentifier+ 1031 | 1032 | ExportDeclaration := 1033 | export * +FromClause+ ; 1034 | export +ExportClause+ +FromClause+ ; 1035 | export +ExportClause+ ; 1036 | export +VariableStatement+; 1037 | export +Declaration+ 1038 | export default +HoistableDeclaration+ 1039 | export default +ClassDeclaration+ 1040 | export default +AssignmentExpression+ ; 1041 | 1042 | ExportClause := 1043 | { } 1044 | { +ExportList+ } 1045 | 1046 | ExportList := 1047 | +ExportSpecifier+ 1048 | 1049 | ExportSpecifier := 1050 | +IdentifierName+ 1051 | +IdentifierName+ as +IdentifierName+ 1052 | 1053 | StringNumericLiteral := 1054 | +StrWhiteSpace+ 1055 | +StrWhiteSpace+ +StrNumericLiteral+ +StrWhiteSpace+ 1056 | 1057 | StrWhiteSpace := 1058 | +StrWhiteSpaceChar+ +StrWhiteSpace+ 1059 | 1060 | StrWhiteSpaceChar := 1061 | +WhiteSpace+ 1062 | +LineTerminator+ 1063 | 1064 | StrNumericLiteral := 1065 | +StrDecimalLiteral+ 1066 | +BinaryIntegerLiteral+ 1067 | +OctalIntegerLiteral+ 1068 | +HexIntegerLiteral+ 1069 | 1070 | StrDecimalLiteral := 1071 | +StrUnsignedDecimalLiteral+ 1072 | ++StrUnsignedDecimalLiteral+ 1073 | -+StrUnsignedDecimalLiteral+ 1074 | 1075 | StrUnsignedDecimalLiteral := 1076 | +DecimalDigits+.+DecimalDigits+ 1077 | .+DecimalDigits+ 1078 | +DecimalDigits+ 1079 | 1080 | uri := 1081 | +uriCharacters+ 1082 | 1083 | uriCharacters := 1084 | +uriCharacter+ 1085 | 1086 | uriCharacter := 1087 | +uriReserved+ 1088 | +uriUnescaped+ 1089 | +uriEscaped+ 1090 | 1091 | uriReserved := 1092 | + 1093 | ; 1094 | / 1095 | ? 1096 | : 1097 | @ 1098 | & 1099 | = 1100 | + 1101 | $ 1102 | , 1103 | + 1104 | 1105 | uriUnescaped := 1106 | +uriAlpha+ 1107 | +DecimalDigit+ 1108 | +uriMark+ 1109 | 1110 | uriEscaped := 1111 | % +HexDigit+ +HexDigit+ 1112 | 1113 | 1114 | uriAlpha := 1115 | a 1116 | b 1117 | c 1118 | d 1119 | e 1120 | f 1121 | g 1122 | h 1123 | i 1124 | j 1125 | k 1126 | l 1127 | m 1128 | n 1129 | o 1130 | p 1131 | q 1132 | r 1133 | s 1134 | t 1135 | u 1136 | v 1137 | w 1138 | x 1139 | y 1140 | z 1141 | A 1142 | B 1143 | C 1144 | D 1145 | E 1146 | F 1147 | G 1148 | H 1149 | I 1150 | J 1151 | K 1152 | L 1153 | M 1154 | N 1155 | O 1156 | P 1157 | Q 1158 | R 1159 | S 1160 | T 1161 | U 1162 | V 1163 | W 1164 | X 1165 | Y 1166 | Z 1167 | 1168 | uriMark := 1169 | - 1170 | _ 1171 | . 1172 | ! 1173 | ~ 1174 | * 1175 | ' 1176 | ( 1177 | ) 1178 | ] 1179 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/old/semantics.dg: -------------------------------------------------------------------------------- 1 | %%% LanguageConstructs API 2 | 3 | %const% VARIANCE_MAX := 1 4 | %const% VARIANCE_TEMPLATE := "function f(){%s} %%DebugPrint(f()); %%OptimizeFunctionOnNextCall(f); %%DebugPrint(f());" 5 | %const% MAX_REPEAT_POWER := 4 6 | 7 | %section% := variable 8 | 9 | variable := 10 | @variable@=+grammar:math+; 11 | 12 | %%% ########################################################################### 13 | 14 | %section% := variance 15 | variance := 16 | var tmp; if (+common:bool+) { tmp=!variable! } else { if (+common:bool+) { tmp=!variable! } } return tmp; 17 | -------------------------------------------------------------------------------- /vasilisk/grammars/templates/variables.dg: -------------------------------------------------------------------------------- 1 | regexptype := 2 | new RegExp("+regexp:pattern+", "+regexp:flags+") 3 | new RegExp("+regexp:pattern+") 4 | RegExp("+regexp:pattern+", "+regexp:flags+") 5 | RegExp("+regexp:pattern+") 6 | 7 | arrtype := 8 | [%repeat%(+value:valtype+, ",")] 9 | [%repeat%(+common:decimal_number+, ",")] 10 | new Array(+common:short_int+) 11 | 12 | bool := 13 | true 14 | false 15 | Boolean(+value:valtype+) 16 | new Boolean(+value:valtype+) 17 | 18 | arraybuffertype := 19 | new ArrayBuffer(+common:positive_integer+) 20 | 21 | typedarraytype := 22 | new +buffer:typedarraykind+(+buffer:typedarrayarg+) 23 | 24 | dataviewtype := 25 | (new DataView(+dataview:dataviewbuffer+)) 26 | (new DataView(+dataview:dataviewbuffer+, +common:int+)) 27 | (new DataView(+dataview:dataviewbuffer+, +common:int+, +common:int+) 28 | 29 | datetype := 30 | Date() 31 | Date.parse("+common:text+") 32 | new Date() 33 | new Date(+common:int+) 34 | new Date(+common:int+, +common:int+) 35 | new Date(+common:int+, +common:int+, +common:int+) 36 | new Date(+common:int+, +common:int+, +common:int+, +common:int+) 37 | new Date(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 38 | new Date(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 39 | new Date.UTC() 40 | new Date.UTC(+common:int+) 41 | new Date.UTC(+common:int+, +common:int+) 42 | new Date.UTC(+common:int+, +common:int+, +common:int+) 43 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+) 44 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 45 | new Date.UTC(+common:int+, +common:int+, +common:int+, +common:int+, +common:int+, +common:int+) 46 | 47 | obj := 48 | {%repeat%(+object:name_value_pair+, ",")} 49 | 50 | maptype := 51 | new Map(+map:map_arg+) 52 | 53 | numbertype := 54 | new Number(+value:valtype+) 55 | new Number(+common:int+) 56 | new Number("+common:int+") 57 | Number(+value:valtype+) 58 | Number(+common:int+) 59 | Number("+common:int+") 60 | Number.EPSILON 61 | Number.MAX_SAFE_INTEGER 62 | Number.MAX_VALUE 63 | Number.MIN_SAFE_INTEGER 64 | Number.MIN_VALUE 65 | Number.NaN 66 | Number.NEGATIVE_INFINITY 67 | Number.POSITIVE_INFINITY 68 | 69 | settype := 70 | new Set(+set:set_arg+) 71 | 72 | stringtype := 73 | "+common:text+" 74 | new String("+common:text+") 75 | 76 | symboltype := 77 | Symbol.iterator 78 | Symbol.match 79 | Symbol.replace 80 | Symbol.search 81 | Symbol.split 82 | Symbol.hasInstance 83 | Symbol.isConcatSpreadable 84 | Symbol.unscopables 85 | Symbol.species 86 | Symbol.toPrimitive 87 | Symbol.toStringTag 88 | 89 | valtype := 90 | +value:nulls+ 91 | +common:int+ 92 | +common:decimal_number+ 93 | +common:short_int+ 94 | +common:intoverflow+ 95 | +common:byte+ 96 | +common:object+ 97 | +common:bool+ 98 | "+common:text+" 99 | +array:arrtype+ 100 | +object:objtype+ 101 | +symbol:symboltype+ 102 | 103 | weakmaptype := 104 | (new WeakMap(+weakmap:weakmaparg+)) 105 | 106 | weaksettype := 107 | (new WeakSet(+weakset:weaksetarg+)) 108 | -------------------------------------------------------------------------------- /vasilisk/grammars/verify.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | import sys 4 | 5 | from .dharma_grammar import DharmaGrammar 6 | 7 | 8 | class VerifyGrammar(DharmaGrammar): 9 | def __init__(self): 10 | self.logger = logging.getLogger(__name__) 11 | 12 | grammar_dir = os.path.join('/dev/shm', 'vasilisk_grammar') 13 | if not os.path.exists(grammar_dir): 14 | self.logger.info('creating coverage dir') 15 | os.makedirs(grammar_dir) 16 | 17 | self.grammar_path = os.path.join(grammar_dir, 'gen_grammar.dg') 18 | with open(self.grammar_path, 'w+'): 19 | pass 20 | 21 | current_dir = os.path.dirname(os.path.realpath(__file__)) 22 | templates = os.path.join(current_dir, 'templates') 23 | 24 | dependencies = os.path.join(templates, 'dependencies') 25 | self.grammar_deps = [ 26 | os.path.join(dependencies, grammar) 27 | for grammar in os.listdir(os.path.join(dependencies)) 28 | ] 29 | 30 | with open(os.path.join(templates, 'actions.dg'), 'r') as f: 31 | self.all_actions = f.read() 32 | 33 | self.actions = self.parse(os.path.join(templates, 'actions.dg')) 34 | self.controls = self.parse(os.path.join(templates, 'controls.dg')) 35 | self.variables = self.parse(os.path.join(templates, 'variables.dg')) 36 | 37 | self.curr_action = 0 38 | 39 | self.grammars = self.grammar_deps + [self.grammar_path] 40 | super().__init__(self.grammars) 41 | 42 | def parse(self, grammar_path): 43 | with open(grammar_path, 'r') as f: 44 | grammar_text = f.read() 45 | 46 | grammar_split = [rule.strip() for rule in grammar_text.split('\n\n')] 47 | rules = {} 48 | 49 | for rule in grammar_split: 50 | title, subrules = [r.strip() for r in rule.split(':=')] 51 | 52 | subrules = [subrule.strip() for subrule in subrules.split('\n')] 53 | for i, subrule in enumerate(subrules): 54 | rules[title + ':' + str(i)] = subrule 55 | 56 | return rules 57 | 58 | def generate(self): 59 | if self.curr_action >= len(self.actions.keys()): 60 | self.logger.info('finished verifying all actions') 61 | sys.exit(1) 62 | 63 | headers = [ 64 | '%%% Generated Grammar', 65 | '%const% VARIANCE_MAX := 1', 66 | '%const% VARIANCE_TEMPLATE := "function f(){%s} %%DebugPrint(f());' 67 | '%%OptimizeFunctionOnNextCall(f); %%DebugPrint(f());"', 68 | '%const% MAX_REPEAT_POWER := 4' 69 | ] 70 | 71 | with open(self.grammar_path, 'w') as f: 72 | for header in headers: 73 | f.write(header + '\n') 74 | 75 | f.write('\n') 76 | 77 | action = list(self.actions.keys())[self.curr_action] 78 | 79 | with open(self.grammar_path, 'a') as f: 80 | f.write('%section% := value\n\n') 81 | f.write(f'action :=\n\t{self.actions[action]}\n\n') 82 | 83 | variable = list(self.variables.keys())[0] 84 | 85 | with open(self.grammar_path, 'a') as f: 86 | f.write('%section% := variable\n\n') 87 | f.write(f'variable :=\n\tvar @variable@={self.variables[variable]}\n\n') 88 | 89 | control = list(self.controls.keys())[0] 90 | 91 | with open(self.grammar_path, 'a') as f: 92 | f.write('%section% := variance\n\n') 93 | f.write(f'variance :=\n\t{self.controls[control]}\n\n') 94 | 95 | self.create_dharma(self.grammars) 96 | self.curr_action += 1 97 | 98 | try: 99 | generated = super().generate() 100 | except RecursionError as e: 101 | self.logger.info(f'invalid rule (recursion): {action}') 102 | sys.exit(1) 103 | 104 | return ((action, control), generated) 105 | -------------------------------------------------------------------------------- /vasilisk/vasilisk.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import logging 3 | import os 4 | import time 5 | 6 | import click 7 | 8 | from multiprocessing import Process, JoinableQueue 9 | 10 | import fuzzers 11 | import grammars 12 | 13 | 14 | class Vasilisk: 15 | def __init__(self, fuzzer, d8, procs, count, 16 | crashes, tests, debug): 17 | self.logger = logging.getLogger(__name__) 18 | 19 | self.procs = procs 20 | self.count = count 21 | self.rate_limit = min(1000 * self.procs, self.count) 22 | 23 | if count < 0: 24 | self.rate_limit = 1000 * self.procs 25 | 26 | self.generated = 0 27 | 28 | self.grammar = grammars.grammars[fuzzer]() 29 | self.fuzzer = fuzzers.fuzzers[fuzzer]( 30 | procs, d8, crashes, tests, debug 31 | ) 32 | 33 | self.queue = JoinableQueue(self.rate_limit) 34 | 35 | self.threads = [] 36 | 37 | if not os.path.exists(crashes): 38 | self.logger.info('creating crashes folder') 39 | os.makedirs(crashes) 40 | 41 | if not os.path.exists(tests): 42 | self.logger.info('creating tests folder') 43 | os.makedirs(tests) 44 | 45 | def generate(self): 46 | while self.generated < self.count or self.count < 0: 47 | grammar = self.grammar.generate() 48 | self.queue.put(grammar) 49 | self.generated += 1 50 | 51 | self.logger.debug(grammar) 52 | self.logger.debug('-' * 50) 53 | 54 | def fuzz(self, thread): 55 | while True: 56 | test_case = self.queue.get() 57 | 58 | if test_case is None: 59 | break 60 | 61 | self.fuzzer.fuzz(test_case, thread) 62 | 63 | self.queue.task_done() 64 | 65 | def start(self): 66 | self.logger.info('my pid is {}'.format(os.getpid())) 67 | start_time = time.time() 68 | 69 | for thread in range(self.procs): 70 | args = (thread,) 71 | t = Process(target=self.fuzz, args=args) 72 | t.daemon = True 73 | t.start() 74 | self.threads.append(t) 75 | 76 | self.generate() 77 | 78 | self.queue.join() 79 | 80 | for _ in range(self.procs): 81 | self.queue.put(None) 82 | 83 | for t in self.threads: 84 | t.join() 85 | 86 | end_time = time.time() 87 | 88 | self.logger.info('finished {} cases in {} seconds'.format( 89 | self.count, end_time - start_time)) 90 | 91 | 92 | @click.command() 93 | @click.option('--fuzzer', required=True, 94 | type=click.Choice(fuzzers.fuzzers.keys()), 95 | default='groups', 96 | help='which fuzzer to use. differences in README') 97 | @click.option('--d8', envvar='D8_PATH', 98 | help='location of d8 executable. defaults to value stored \ 99 | in D8_PATH environment variable') 100 | @click.option('--procs', default=8, help='worker processes to create') 101 | @click.option('--count', default=10, help='number of iterations') 102 | @click.option('--crashes', default='./crashes', 103 | help='where to store crash findings') 104 | @click.option('--tests', default='/tmp/vasilisk/tests', 105 | help='where to store inputs if debug mode on') 106 | @click.option('--debug', is_flag=True, default=False, 107 | help='debug mode turns on more debug messages and stores all \ 108 | test inputs to specified test folder') 109 | @click.option('--verbose', is_flag=True, default=False, 110 | help='print more stuff') 111 | def main(fuzzer, d8, procs, count, crashes, tests, debug, verbose): 112 | if verbose: 113 | logging.basicConfig(level=logging.DEBUG) 114 | else: 115 | logging.basicConfig(level=logging.INFO) 116 | 117 | driver = Vasilisk( 118 | fuzzer, d8, procs, count, crashes, tests, debug 119 | ) 120 | driver.start() 121 | 122 | 123 | if __name__ == "__main__": 124 | main() 125 | --------------------------------------------------------------------------------