README

marianoguerra/wax/syntax/parser does not have a README file

#
SyntaxError

type SyntaxError derive(
Debug
)

A syntax error raised from a semantic action.

Distinct from MoonYacc's own ParseError, which reports a token the automaton could not shift. These are the errors the reference raises from inside its actions -- "this identifier is not a value type", "a parameter list is required" -- where the token stream is fine but what it says is not. Their message text is hand-written in the reference, so unlike the automaton messages it can be reproduced exactly.

#
ErrorState

pub struct ErrorState {
state : Int
stack : Array[Int]
token_index : Int
spans : Array[(
Position
,
Position
)]
}

Where a parse ran aground, in the automaton's terms.

#
ErrorState::subject_span

The construct the parser was in the middle of, as a span.

The reference's Assuming that the X is complete messages carry a label pointing AT that X. Menhir names it by the reductions it performs once the error token is in hand -- annotated %on_error_reduce -- and the completed construct is what the outermost of them pushes.

Nothing here has those annotations, so this reduces while the reduction is unambiguous: a state whose only reduce action, over every terminal lookahead, is one production. That is the same move for the same reason, and where it is not the same the span simply does not match the reference's and the label is dropped (see the calibration in tools/gen_parser_messages.py).

None when the stack does not reduce at all, or when the construct is empty -- underlining nothing is noise, which is the rule the reference applies to an epsilon reduction too.

#
HintSetter

type HintSetter derive(
Debug
)

What a hint attribute asks for, before it has been checked against the instruction it prefixes.

#
enclosing_opener

The innermost delimiter still open at the failure.

The reference's This '{' opens the enclosing construct. label points at the opener of the construct the error is inside. It reaches it through a parser-stack cell; the same token is what a bracket scan of everything shifted so far finds, so that is what this does -- and it needs no correspondence between two automata's stack layouts.

None when nothing is open, which is when the reference emits no such label either.

#
error_state

Replay tokens through the automaton and report where it fails.

None when the input parses -- callers only ask after a real parse has already failed, so None means the replay disagrees with the parse, and the caller falls back rather than trusting a state it cannot explain.

Mirrors the generated yy_parse decision for decision. The differences are that nothing is built (no data stack, no actions run, so a grammar action's side effects cannot fire twice) and that the loop reports the failure rather than raising.

#
expected_signature

fn expected_signature(expected : Array[
TokenKind
]) -> String

A signature of the acceptable-token set, for the message table.

A stack suffix alone is not enough to borrow the reference's message: the same top frames occur in contexts whose continuations differ (a type definition inside a rec { … } group accepts '}', the same construct at the top level does not), and a message from the wrong one claims a token is legal when it is not. The acceptable set IS that difference, so the table records it and the lookup checks it.

Deliberately the raw spellings rather than the rendered message: the rendering has opinions (class collapse, ordering) that may change, and this wants to change only when the automaton does.

#
parse_recover

fn parse_recover(src : String, fname? : String) -> ParseResult

A parse that reports every syntax error it can resynchronize past.

The module is best-effort: whatever the actions built from the parts that did parse, or None if recovery never got the automaton back to an accept.

#
parse_string

fn parse_string(src : String, fname? : String) -> ParseResult

Parse src.

Three failure paths, all funnelled into errors:

  • a LEXICAL error, which stops the scan (lexer.tokens_from_string);
  • a SEMANTIC error raised from a grammar action -- recorded rather than raised, since MoonYacc's actions cannot propagate one;
  • a SYNTAX error from the automaton itself, ParseError.

#
set_context