cyclone-analyzer
Version:
A static analyzer library for Cyclone specification language
190 lines (135 loc) • 5.79 kB
Markdown
# Cyclone Analyzer
Cyclone analyzer is a static analyzer for [Cyclone Specification Language](https://classicwuhao.github.io/cyclone_tutorial/tutorial-content.html). This library powers the [cyclone online editor](https://github.com/lucid-brndmg/cyclone-online-editor) project.
The analyzer covers most of Cyclone's language features. This package also contains the language specification, an IR builder, some utility functions, a parser and a lexer based on ANTLR4 for Cyclone. This analyzer currently checks for 40+ kinds of semantic errors in a Cyclone spec, and would be helpful as a linter for Cyclone code editors.
**Limitations:** This analyzer performs a static analysis for each Cyclone specification. The semantic errors detected by this analyzer are not comprehensive: Certain errors can not be discovered by this analyzer. If this analyzer report no error on a certain specification, it doesn't mean the specification actually has no problem at all.
*This project is a part of my final year project (CS440[A]) at Maynooth University.*
## TODO
- This document is unfinished and will be updated in the future.
## Usage
### Installation
Use npm or yarn to install:
```shell
npm install cyclone-analyzer
```
Import this library using `import` or `require`:
```javascript
// ESM
import cycloneAnalyzer from "cyclone-analyzer"
// CJS
const cycloneAnalyzer = require("cyclone-analyzer")
```
### Analyze a Cyclone Specification
Find errors in any Cyclone specification by simply using `analyzeCycloneSpec`.
```javascript
import {analyzer} from "cyclone-analyzer"
const cycloneSpec = `
graph G {
int i = 1;
start normal node S0 {
i ++;
}
final normal node S1 {
i --;
}
edge {S0 -> S1}
goal {
assert i == 1 in (S1);
check for 1
}
}
`
const result = analyzer.analyzeCycloneSpec(cycloneSpec)
if (result.hasSyntaxError()) {
console.log("This spec has syntax error:", result.parserErrors)
} else if (result.hasSemanticError()) {
console.log("Semantic errors detected:", result.semanticErrors)
} else {
console.log("This spec seems ok")
}
```
### Parsing
Use `utils.antlr.parseCycloneSyntax` to parse a Cyclone specification via ANTLR4:
```javascript
import cycloneAnalyzer from "cyclone-analyzer"
const {parseCycloneSyntax} = cycloneAnalyzer.utils.antlr
const spec = `
graph G {
int i = 1 // syntax error: a semicolon is required here
}
`
const parsed = parseCycloneSyntax({input: spec})
if (parsed.syntaxErrorsCount > 0) {
console.log("This spec has syntax error")
}
```
### Syntax Block Builder
There is an IR builder `blockBuilder.SyntaxBlockBuilder` for building a tree-structured context for a Cyclone spec after semantic analysis:
```javascript
import {analyzer, blockBuilder} from "cyclone-analyzer"
const cycloneSpec = `
graph G {
start final node A {}
edge {A -> A}
goal { check for 1 }
}
`
const irBuilder = new blockBuilder.SyntaxBlockBuilder()
const analysisResult = analyzer.analyzeCycloneSpec(cycloneSpec, {
analyzerExtensions: [irBuilder] // the builder is an extension of the analyzer
})
// the syntax block of the input Cyclone spec, as a tree
const program = irBuilder.getProgramBlock()
console.log(program)
```
### Analyzer Extensions
The semantic analyzer defined series of events and can be listened with `analyzer.on` method. In this way, extensions can be written by listening to analyzer events. Extensions can be objects or class instances that has an `attach` method:
```javascript
import {analyzer} from "cyclone-analyzer"
// defining an extension as class
class MyExtension {
// the required attach method
attach(analyzer) {
// this.analyzer = analyzer
analyzer.on("errors", (ctx, errors) => console.log("semantic errors discovered:", errors))
analyzer.on("block:enter", (ctx, payload) => console.log("entering a semantic context block"))
analyzer.on("block:exit", (ctx, payload) => console.log("exiting a semantic context block"))
analyzer.on("identifier:register", (ctx, {text}) => console.log("registering identifier: ", text))
analyzer.on("identifier:reference", (ctx, {references}) => console.log("referencing identifiers: ", references))
}
}
const cycloneSpec = `
graph G {
start final node A {}
edge {A -> A}
goal { check for 1 }
}
`
const ext = new MyExtension()
const analysisResult = analyzer.analyzeCycloneSpec(cycloneSpec, {
analyzerExtensions: [ext] // attach the extension
})
```
## Modules
This package contains the following modules:
| Module | Description | Status |
|----------------|----------------------------------------------------------------------|----------|
| `analyzer` | The semantic analyzer for Cyclone | Stable |
| `blockBuilder` | An IR builder based on the semantic analyzer | Unstable |
| `generated` | The generated lexer and parser based on ANTLR4 | Stable |
| `language` | The language's definitions in enums & specifications | Stable |
| `library` | Some libraries that has nothing to do with the language itself | Stable |
| `utils` | Helper modules for analyzer and block builder to handle the language | Stable |
### Analyzer
TODO
### Block Builder
TODO
### Generated Lexer & Parser
TODO
### Language Definitions & Specifications
TODO
### Library
TODO
### Utilities
TODO
## License
Published under the [BSD-2 license](https://www.tldrlegal.com/license/bsd-2-clause-license-freebsd)