SMLYACC(1)
π SMLYACC(1) π
okay bestie, welcome to smlyacc, from the General Commands Manual section of your friendly neighborhood man pages. this one's the parser generator for SML#, and yes she is iconic, let's get into it π«Ά
β¨ NAME β¨
smlyacc β the parser generator for SML#, periodt π
β¨ SYNOPSIS β¨
smlyacc [-s] [-p output_prefix] filename
β¨ DESCRIPTION β¨
so SMLYacc is a parser generator, and she's serving major ML-Yacc energy. like, she'll accept grammar files written for ML-Yacc β no problem, come as you are π₯° β BUT. and this is important bestie. the programs she generates, and the way you use them, are not compatible with the ones ML-Yacc makes. not the same vibe at all. the good news? the programs she generates can be compiled by the SML# compiler. slay.
okay so here's the default situation. for an input file X.grm, smlyacc generates:
X.grm.smlβ for the generated parserX.grm.sigβ for the signature of tokens- and optionally
X.grm.descβ the description of the LALR parser construction
and to compile that generated program with SML#, you have to write an interface file X.grm.smi by yourself, matching up with the generated signature X.grm.sig. yes, by hand. i know. it's giving β¨character buildingβ¨. you got this tho.
β¨ OPTIONS β¨
-sβ insert the token signature at the beginning of the generated.smlfile, instead of making a separate.sigfile. one file, no crumbs π-poutput_prefixβ sets the prefix for the output file names. whenoutput_prefixisX, thensmlyaccgeneratesX.sml,X.sig, andX.desc. the default is the same as the input file name, no cap π―
β¨ EXAMPLES β¨
here's a minimal little example of an input file, ex.grm πΈ
%%
%term LPAREN | RPAREN | EOF
%nonterm start of word | exp of word
%pos int
%eop EOF
%name Example
%%
start : exp (exp)
exp : (0w0)
| LPAREN exp RPAREN exp (exp1 + exp2)
and when you run this file through smlyacc, like so:
smlyacc ex.grm
you get two files back: ex.grm.sml and ex.grm.sig π only ex.grm.sml actually needs to be compiled. but to compile it, you've gotta create this ex.grm.smi file yourself, bestie:
_require "basis.smi"
_require local "ml-yacc-lib.smi"
_require local "./ex.grm.sig"
structure ExampleLrVals =
struct
structure Parser =
struct
type token (= boxed)
type stream (= ref)
type result = word
type pos = int
type arg = unit
val makeStream : {lexer : unit -> token} -> stream
val consStream : token * stream -> stream
val getStream : stream -> token * stream
val sameToken : token * token -> bool
val parse : {lookahead : int,
stream : stream,
error : string * pos * pos -> unit,
arg : arg}
-> result * stream
end
structure Tokens =
struct
type pos = Parser.pos
type token = Parser.token
val EOF: pos * pos -> token
val RPAREN: pos * pos -> token
val LPAREN: pos * pos -> token
end
end
the types of those token constructors β EOF, RPAREN, and LPAREN β get copied straight out of the generated signature file ex.grm.sig, by hand. yes, manually. iykyk π
so the parse function in the generated program is the parser. to invoke it you need an imperative lexer function of type unit -> token. and if you're combining with SMLLex, the lexer is generated by SMLLex. let's say SMLLex generates a lexer with this interface:
structure ExampleLex =
struct
exception LexError
val makeLexer : (int -> string)
-> unit -> ExampleLrVals.Parser.token
end
then a typical piece of code joining SMLLex and SMLYacc together looks like this, and it ate, no notes π :
fun inputN n = TextIO.inputN (instream, n)
val lexer = ExampleLex.makeLexer inputN
val stream = ExampleLrVals.Parser.makeStream {lexer = lexer}
val (result, stream) =
ExampleLrVals.parse
{lookahead = 0, stream = stream,
error = errorFn, arg = parserArg}
β¨ HISTORY β¨
fun fact bestie π¦ SMLYacc is a derivative of ML-Yacc, which was originally developed by David R. Tarditi and Andrew W. Appel. when ML-Yacc got ported over to SML#, the source code got restructured so that functor applications were replaced with SML#'s separate compilation and linking. main character rewrite energy fr fr. and for all the major changes from the original ML-Yacc, go check the SML# document π
β¨ SEE ALSO β¨
smllex(1)ML-Yacc User's Manual, available athttps://www.smlnj.org/doc/ML-Yacc/SML# Document, available athttps://www.pllab.riec.tohoku.ac.jp/smlsharp/docs/
and that's the whole page, gorgeous π this one's from the SMLYACC(1) manual page in the General Commands Manual section β go forth and generate some parsers, you absolute legend πβ¨π
π¦ where this page comes from
- debian trixie: smlsharp 4.1.0-1+b1 Β· MIT
- ubuntu jammy: smlsharp 4.0.0+git20211227.5af5945b-1 Β· MIT
- ubuntu noble: smlsharp 4.0.0+git20211227.5af5945b-2 Β· MIT
- ubuntu questing: smlsharp 4.1.0-1
- ubuntu resolute: smlsharp 4.1.0-1.1 Β· MIT
- ubuntu stonking: smlsharp 4.1.0-1.1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms