Version 0.1.7 adds the first real Language Server connection. The Theia/VS
Code extension starts out/server.js through vscode-languageclient; the
server invokes a configured executable containing the generated Coco/R
parser/validator.
Coco/R itself is a compiler-compiler: it generates a scanner/parser from an
.atg grammar. It is therefore not run for every keystroke. The editor runs
the generated validator instead.
"modula2.cocoR.validatorCommand": "/path/to/generated-modula2-validator",
"modula2.cocoR.validatorArguments": ["{file}"]
{file} is replaced by a temporary copy of the current .mod or .def
document. The validator is run with the original document directory as its
working directory.
The server understands the editor-oriented Coco/R output used by the CRQ
frame:
source.mod (12,7) message
Line numbers are converted from one-based to LSP zero-based positions.
When validatorCommand is empty, the LSP publishes no Coco/R diagnostics;
the existing lightweight diagnostics remain available.
GNU-grammar/bin/GM2 is a validator built from the tested
gm2-gcc-0.2 grammar. Besides the .LST listing file, it prints one
editor-oriented diagnostic per error to standard output:
/tmp/.../multi.mod (3,0) 'MODULE' expected
/tmp/.../multi.mod (5,15) invalid SetOrDesignatorOrFunction
Line numbers are one-based, columns are zero-based, matching the
file (line,column) message pattern above. A clean file prints only
Parsing / Parsed correctly (no diagnostic lines).
Example configuration:
"modula2.cocoR.validatorCommand": "/home/eric/Projets/Projets-Modula2/MyWork/Theia/GNU-grammar/bin/GM2",
"modula2.cocoR.validatorArguments": ["{file}"]
The reference grammar lives at grammars/Modula2.atg (copy of the
tested gm2-gcc-0.2.atg); parser regression tests live in
grammars/tests/ and are checked with
<GNU-grammar>/bin/GM2 <test>.mod (expect 0 errors).
gm2 -fiso)Measured with bin/GM2 against gm2 16.0.1: 21 real files
(m2compiler-V3, m2-sunrise, hello), 22 accepted-construct probes and
9 broken probes. GM2 is syntax-only by design — it never type-checks,
so semantic errors (unknown names, type mismatches, bad arities) are
always missed and do not count below. GM2 exits 0 either way;
consumers must parse stdout.
FORWARD procedure
headings (85 diags on the generated M2P.mod): the grammar's
ProcedureDeclaration = ProcedureHeading ";" ( ProcedureBlock Ident )
has no FORWARD alternative, while gm2 accepts it. Probable fix:
( "FORWARD" | ProcedureBlock Ident ) (plus regenerating the
validator with the Coco/R toolchain).FORWARD gap. WITH, CASE/ELSE,
REPEAT, LOOP/EXIT, nested comments, set constructors, all
literal forms, BY -1 steps and the empty module all parse.END-name mismatch (unchecked).
Two probes were correctly not errors: gm2 itself only warns on a
missing ; before END and on an unclosed ( (separator/recovery
leniency), and GM2 agrees with it..pas / .pp / .p)The same server validates Pascal files with the pilot validators from
grammars/. Each pilot binary takes the source file as its single
argument and writes a .LST listing next to it; the server parses the
listing's ***** ^ message lines (positions are caret-relative to the
code after the listing prefix, zero-based columns).
"modula2.pascal.dialect": "freepascal",
"modula2.pascal.validators": {
"p2": "<root>/grammars/P2/build/P2",
"p4": "<root>/grammars/P4/build/P4",
"p6": "<root>/grammars/P6/build/P6",
"pascal": "<root>/grammars/Pascal/build/PStd",
"turbopascal3": "<root>/grammars/TurboPascal3/build/TP3",
"freepascal": "<root>/grammars/FreePascal/build/FPC",
"blaise": "<root>/grammars/Blaise/build/BlaiseV",
"pascals": "<root>/grammars/PascalS/build/PascalS"
}
Build each binary first with its pilot build.sh (needs CR and
gm2 -fiso). The local Modula-2 analysis never runs on Pascal text.
With no command configured for the active dialect the server publishes
no diagnostics. Never point these at the pcom/psc oracle compilers
— they can hang on invalid input.