Skip to main content
Version: Next

SAS Parser

This is a parser for the SAS language.

It is intended to be used mainly as a JVM library. It can also be used as a command line tool.

The parser works in three different stages:

  • First a list of tokens are created from some input stream (typically a File)
  • Then a parse-tree is obtained by grouping the tokens and recognizing structures
  • Finally an Abstract Syntax Tree (AST) is derived from the parse-tree. While the AST resembles closely the parse-tree it contains re-arrangements and simplifications that makes easier working with it.

The AST is built using the Kolasu library. This open-source library has been built by Strumenta. This tutorial on Kolasu explains how the library can be used: Building advanced parsers using Kolasu.

The AST could be used to perform analysis on the code or transformations of the code.

An example of transformations that can be created is transpilation.

Contents of the package

  • Full JAR file with all dependencies
  • Windows e Linux scripts to execute the JAR
  • Documentation in HTML format

How to use the parser

You can use the parser as a library (i.e., from code) or as a standalone program, from the command line.

How to use from the command line

This document describes how to use the SAS parser from the command line. The CLI is implemented in com.strumenta.sas.parser.Main and is distributed as a standalone JAR together with launcher scripts for Windows and Linux.

Prerequisites

  • Java Runtime Environment (JRE) on the classpath. The parser has been tested with JVM 11. Serialization issues have been reported with JVM 16 and later.
  • A valid Strumenta license file for all parsing commands (parse, jsonast, and model). Parsing will not run unless a license is registered with --license.

Invoking the CLI

Run the JAR with java -jar:

java -jar sas-parser-with-dependencies-<version>-all.jar [GLOBAL_OPTIONS] COMMAND [COMMAND_OPTIONS] [ARGUMENTS...]

Running the JAR without a subcommand prints the top-level help.

Command-name casing

Subcommand names are case-sensitive. Use the exact spelling below:

Correct nameCommon mistake
jsonastjsonAst, jsonAST, JsonAst
downloadlicensedownloadLicense, download-license
parse
model
metamodel
Global options

These options apply to the parser configuration and must be placed before the subcommand name:

OptionDescription
--parse-native-sqlWhen set, native SQL fragments embedded in SAS code are parsed during post-processing. Off by default.
--report-error-nodesWhen set, ErrorNode instances in the AST are reported as semantic issues. Enabled by default; the flag is present mainly for explicit documentation of the behavior.
-h, --helpShow top-level help.

Example:

java -jar sas-parser-with-dependencies-<version>-all.jar --parse-native-sql parse --license=my.license example.sas
License

Most commands require a commercial license.

Commands that require --license
CommandOptionRequirement
parse--license PATHRequired. Path to an existing, readable license file.
jsonast--license PATHRequired.
model--license PATHRequired.

The license path can be passed as --license path/to/file.license or --license=path/to/file.license.

The license file must exist and be readable. Symlinks are accepted.

Commands that do not require a license
CommandPurpose
downloadlicenseDownload a new license from the Strumenta license service.
metamodelGenerate the EMF metamodel for the SAS AST (no parsing of user SAS files).
Downloading a license

Use downloadlicense to obtain or refresh a license. Provide your credentials and the destination path:

java -jar sas-parser-with-dependencies-<version>-all.jar downloadlicense USERNAME PASSWORD path/to/license.file

On success, the CLI prints confirmation and the license validity period:

License successfully downloaded at path/to/license.file
StartDate: Mon Nov 04 01:00:00 CET 2024
EndDate: Sat Dec 07 01:00:00 CET 2024

Downloaded licenses expire depending on your subscription or contract. Anytime you download a license, it will be downloaded with the updated expiration date.

Commands

parse — parse a single file to stdout

Parses one SAS file and writes the parsing result to standard output.

java -jar sas-parser-with-dependencies-<version>-all.jar parse --license=my.license [OPTIONS] FILE
OptionDescription
--license PATHRequired. License file.
-f, --format [json]Output format. Only json is available (default).
-h, --helpShow command help.

Arguments

ArgumentDescription
FILERequired. Path to a single .sas file. Must exist, be a regular file, and be readable.

Example

java -jar sas-parser-with-dependencies-<version>-all.jar parse --license=strumenta.license examples.sas

The JSON output on stdout contains the AST (root) and any parsing issues.


jsonast — export AST as JSON files

Parses one or more SAS files or directories and writes one JSON file per input file.

java -jar sas-parser-with-dependencies-<version>-all.jar jsonast --license=my.license [OPTIONS] [INPUTS]... [OUTPUT]
OptionDescription
--license PATHRequired. License file.
-c, --charset TEXTCharset used to read input files. Default: UTF-8.
--ignore-positions / --consider-positionsControl whether source positions are included in the AST.
-v, --verbosePrint additional progress messages.
-h, --helpShow command help.

Arguments

ArgumentDescription
INPUTSOne or more files or directories to parse. When omitted, behavior depends on the remaining arguments (see below).
OUTPUTOptional output directory (not a file). Defaults to the current working directory. The directory is created if it does not exist.

Output layout

  • Single file input: writes <output-dir>/<basename-without-.sas>.json.
  • Directory input: recursively walks the directory tree. Only files whose name ends with .sas (case-insensitive) are processed. The output mirrors the input directory structure under OUTPUT/<input-directory-name>/.

Example

java -jar sas-parser-with-dependencies-<version>-all.jar jsonast --license=strumenta.license examples.sas .

model — export AST as EMF models

Parses input files and saves each AST as an EMF model (JSON or XMI), together with a metamodel description.

java -jar sas-parser-with-dependencies-<version>-all.jar model --license=my.license [OPTIONS] [INPUTS]...
OptionDescription
--license PATHRequired. License file.
-c, --charset TEXTCharset used to read input files. Default: UTF-8.
--ignore-positions / --consider-positionsControl whether source positions appear in the AST.
-v, --verbosePrint additional progress messages.
--metamodel PATHPath to an existing metamodel file to reuse. When omitted, a metamodel is generated next to each output file as metamodel.json or metamodel.xmi.
-o, --output PATHOutput directory. Default: current directory (.).
-imm, --include-metamodelEmbed the metamodel inside each saved model file. Off by default.
--xmiSave models as .xmi instead of .json. Off by default.
-h, --helpShow command help.

Arguments

ArgumentDescription
INPUTSOne or more SAS files or directories to parse (same conventions as jsonast).

Output layout

For each input file, the CLI writes a model file under --output, preserving the relative path of the input. The file extension is .json by default, or .xmi when --xmi is set. A metamodel file is saved alongside the model unless --metamodel points to an existing one.

Example

java -jar sas-parser-with-dependencies-<version>-all.jar model --license=strumenta.license -o ./out --verbose myprogram.sas

metamodel — generate the AST metamodel

Generates the EMF metamodel for the SAS language. This command does not parse user SAS code and does not require a license.

java -jar sas-parser-with-dependencies-<version>-all.jar metamodel [OPTIONS]
OptionDescription
-o, --output PATHFile where the metamodel is stored.
-ik, --include-kolasuInclude Kolasu types in the exported metamodel.
-v, --verbosePrint additional progress messages.
-h, --helpShow command help.

Example

java -jar sas-parser-with-dependencies-<version>-all.jar metamodel -o build/metamodel/SAS.xmi -v

downloadlicense — download a license

Described in Downloading a license above.

Getting help

Help is available at every level:

# Top-level help and command list
java -jar sas-parser-with-dependencies-<version>-all.jar --help

# Help for a specific command
java -jar sas-parser-with-dependencies-<version>-all.jar parse --help
java -jar sas-parser-with-dependencies-<version>-all.jar jsonast --help
java -jar sas-parser-with-dependencies-<version>-all.jar model --help
java -jar sas-parser-with-dependencies-<version>-all.jar metamodel --help
java -jar sas-parser-with-dependencies-<version>-all.jar downloadLicense --help

Quick reference

GoalCommand
Print AST JSON on stdoutparse --license=… FILE
Write AST JSON files to a directoryjsonast --license=… INPUT [OUTPUT_DIR]
Write EMF model filesmodel --license=… -o OUT_DIR INPUT…
Generate the language metamodelmetamodel -o PATH
Obtain a licensedownloadLicense USER PASS PATH
Parse embedded native SQLAdd --parse-native-sql before the subcommand

How to use as a library

You can use this parser as any other library, directly from your code.

Download a license

You can also download an updated license using the method download license in the LicenseValidation class.

LicenseValidation lv = new LicenseValidation();
lv.downloadLicense("user", "pass", "location.license");

Using a license

This parser requires a license to be used. You can use the static method registerLicense to register the license by providing the license file as argument. You need to register the license once in the program.

import com.strumenta.sas.parser.SASLanguage;
[..]
SASLanguage.Companion.registerLicense(new File("data/example.license"));

You can then instantiate the parser to parse your SAS code (either as a string or as a file).

SASLanguage sasLanguage = new SASLanguage();
sasLanguage.parse(input);

Consult the cookbook for more examples of uses of the parser.