Skip to content

Parser Command Reference

Abe Pralle edited this page Nov 24, 2021 · 18 revisions

A .froley file should have one parser section which is comprised of any number of routines.

The Parser turns a token stream into an Abstract Syntax Tree (AST) of extended Cmd nodes.

Routines

- routine_name
  ...  # commands

- another_routine
  ...

The topmost routine is the default routine. It is called to parse a token stream by default; other Parser routines may be explicitly called if desired.

Routines cannot accept arguments or return values (use global variables if needed).

Parser routines automatically return at the end if no explicit return command is given.

Variables

x = "creating a global variable called x"
if (consume(x)) ...
  • Variables are created simply by assigning a value to a name.
  • All variables are global variables (accessible to all Parser routines).
  • Variables are statically typed. The static type of a variable is implicitly determined by the type of the first value assigned it.
  • Variables can be used to pass values into or out of routines.

Built-in Variables

Name Description
content Read-only. See Creating Nodes.

Literals

"abc"  # a String
'a'    # a Character
123    # an Integer
true   # Logical true
false  # Logical false

Strings and Characters are mostly interchangeable. The only caveat is if the initial value of a variable is a Character, it will not be able to later store a String.

Statements

Statement Description
++ Increment operator. Increment variables with ++varname or varname++.
-- Decrement operator. Decrement variables with --varname or varname--.
-> NodeType(...) -> is an alias for produce.
routine-name Call the named routine. If the routine does not produce or restart then control will return to the following line.
call user-routine-name Call an arbitrarily-named user routine AKA "native routine". The routine is not defined in the .froley file, but rather in the Parser class that Froley generates. Define the method there.
create NodeType
create NodeType(args)
Push a new Cmd node on the internal stack and continue execution. See Creating Nodes.
createList
createList ListType
Creates a CmdList or extended CmdList node that contains all the nodes on the stack since the most recent beginList command. The resulting list is pushed back on the stack.
createNull Pushes a null reference onto the node stack.
discardList Cancels the most recent beginList. The stack is unaltered.
discardPosition Discards the most recent savePosition.
mustConsume("symbol")
mustConsume(TOKEN_TYPE)
If the next token matches the specified type, read and discard it. Otherwise throw an error.
noAction Does nothing. Useful as a placeholder single command for if & while.
print arg1 [arg2...] Prints one or more expressions without a newline.
println arg1 [arg2...] Prints one or more expressions followed by a newline.
produce NodeType
produce NodeType(args)
Executes a create NodeType(...) and then returns from the current routine.
produceNull Pushes a null reference on the stack and then returns from the current routine.
produceList
produceList ListType
Executes a createList ... and then returns from the current routine.
restorePosition Rewinds the input to the point of the most recent savePosition.
return Returns from the current routine. If execution reaches the end of a parser routine a return happens automatically.
savePosition Saves the current input position (line and column, etc.) to be either rewound to with restorePosition or else discarded with discardPosition.
syntaxError
syntaxError "message"
Throws a CompileError with either a default "unexpected input" message or a custom message.

Control Structures

Control Structure Description
if (condition) ...
elseIf (condition) ...
else ...
Single line if statement; separate multiple commands with ;.
if (condition)
  ...
elseIf (condition)
 ...
else
  ...
endIf
Multi-line line if statement.
on token-type
  ...
elseOn token-type
  ...
elseOthers
  ...
endOn
Attempts to read a token of the specified type. If successful, makes it the current token that is stored with any new Cmd node created within the on block. If the token type doesn't match the next token, the optional elseOn blocks are checked and so forth.
on token-type additional-terms -> NodeType(...) on-produce is a shorthand version of on that allows a list of additional routine calls and token types to be specified after the initial token type. The on performs a matching decision on the first token type and then treats the remaining parse terms as "must-reads". For example, on '(' expression ')' -> Expression(operand) is equivalent to:

on '('
  expression
  expression
  mustConsume(')')
produce Expression(operand)
endOn
while (condition) ... Single line while loop; separate multiple commands with ;.
while (condition)
  ...
endWhile
Multi-line while loop.

Expressions

Expressions result in a value that can be used as a condition for if or while. They can also be used as standalone statements.

Operators

Operator Description
( expression ) Standard precedence operator.
+, -, *, /, ^ Add, subtract, multiply, divide, power.
==, !=, <=, >=, <, > Comparison Operators
not Logical not - if (not hasAnother) ....
and, or Logical AND and OR. if (hasAnother and nextIs(';')) ....

Terms

Expression Description
consume("symbol")
consume(TOKEN_TYPE)
Read and discard the next token if it matches the specified type. Evaluates to true on success.
hasAnother Evaluates to true if another input token is available.
nextHasAttribute(attribute-name) Returns true if the next token has the named attribute - if (nextHasAttribute(content)) ....
nextIs("symbol")
nextIs(TOKEN_TYPE)
Evaluates to true if the next available token has the specified type.
read Reads the next input token.

Creating Nodes

  • Commands create XYZ and produce XYZ will create a new extended Cmd node called XYZ and push it on the stack.
  • If arguments create XYZ(alpha,beta) are given, then XYZ is given properties alpha:Cmd and beta:Cmd. Two values are popped off the stack and assigned to beta and then alpha before the XYZ node is pushed on the stack.
  • Specific property types can be declared: create Routine(name:String,statements:Statements). Each property still pops one node off the stack, but in the case of String or Integer (etc.), that node's to->String or to->Int32 (etc.) method is called to convert the node into a value.
  • There are five built-in types: String, Real, Integer, Character, and Logical. Any other type names are assumed to be the names of extended Cmd types.
  • Node properties can be assigned the value content: on STRING -> LiteralString(value=content). When this happens, instead of popping off a node from the stack, value gets its value from the string content of the associated token. Assigning content to a property makes it a String property by default unless another built-in type is declared.
  • Finally, node properties can be assigned an arbitrary string of native code. The content of the string, as native code, is assigned to the property. For example, create LiteralLogical(value="true") initializes value with the value true, not with the string "true".

Example

From the Simple-Parser scanner example.

Clone this wiki locally