Elements
Usage
[rexx] elements [options] file
Transform file into a list of elements, according to options, and print the list.
Options
--tutor |
Enable TUTOR-flavored Unicode |
-u ,
--unicode |
Enable TUTOR-flavored Unicode |
Program source
#!/usr/bin/env rexx
/******************************************************************************/
/* */
/* elements.rex - Transform a file into a list of elements */
/* ======================================================= */
/* */
/* This file is part of the Rexx Parser package */
/* [See https://rexx.epbcn.com/rexx.parser/] */
/* */
/* Copyright (c) 2024-2025 Josep Maria Blasco <josep.maria.blasco@epbcn.com> */
/* */
/* License: Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0) */
/* */
/* Version history: */
/* */
/* Date Version Details */
/* -------- ------- --------------------------------------------------------- */
/* 20241206 0.1 First public release */
/* 20250103 0.1f Add TUTOR-flavored Unicode support */
/* 20250215 0.1g Rename to elements.rex */
/* */
/******************************************************************************/
--------------------------------------------------------------------------------
-- Introspect a little and load our dependencies --
--------------------------------------------------------------------------------
-- Errors returned by the parser require special handling
Signal On Syntax
package = .context~package
-- Jump over the "Requires" routine
Signal Start
Requires:
package~addPackage( .Package~new( Arg(1) ) )
Return
Start:
-- ::REQUIRES does not work well with "../" paths
myName = package~name
mypath = FileSpec( "Path", myName )
myDrive = FileSpec( "Drive", myName )
Parse Caseless Value FileSpec( "Name", myName ) With myName".rex"
-- Create "..", for legibility
package~local["."] = .File~new(myDrive||mypath"..")~absolutePath
Call Requires .."/Rexx.Parser.cls"
Call Requires .."/modules/print/print.cls"
--------------------------------------------------------------------------------
-- Main program --
--------------------------------------------------------------------------------
unicode = 0
Parse Arg file
ProcessOptions:
Parse Var file option file
If option[1] == "-" Then Do
Select Case Lower(option)
When "-u", "--tutor", "--unicode" Then unicode = 1
Otherwise
Say "Invalid option '"option"'."
Exit 1
End
Signal ProcessOptions
End
Else file = option file
file = Strip(file)
-- Display help if appropriate
If file = "" | -
(Words(file) == 1 & "--help /?"~caselessContainsWord(file) ) Then Do
Say .Resources[Help]~makeString~caselessChangeStr("myName", myName)
Exit 1
End
-- Filename may contain blanks
c = file[1]
If """'"~contains(c) Then Do
If \file~endsWith(c) Then Signal BadArgument
file = SubStr(file,2,Length(file)-2)
If file~contains(c) Then Signal BadArgument
End
-- Check that our file exists
If Stream(file,'c','q exists') == "" Then Do
Say "File '"file"' not found."
Exit 1
End
-- We need to compute the source separately to properly handle syntax errors
source = CharIn(file,1,Chars(file))~makeArray
Call CharOut file
-- Print a nice prolog
Say myName".rex run on" Date() "at" Time()
Say
Say "Examining" Strip(Arg(1))"..."
Say
Say "Elements marked '>' are inserted by the parser."
Say "Elements marked 'X' are ignorable."
Say "Elements marked 'A' have isAssigned=1."
Say "Compound symbol components are distinguished with a '->' mark."
Say
Say "[ from : to ] >XA 'value' (class)"
Say " --------- --------- --- ---------------------------"
-- Parse our program, and get the first element
If Unicode Then
parser = .Rexx.Parser~new(file, source, Array(("UNICODE", 1)) )
Else
parser = .Rexx.Parser~new(file, source)
element = parser~firstElement
-- Iterate over all elements and print them
elements = 0
Do Counter elements Until element == .Nil
Call Print element
element = element~next
End
Say "Total:" elements "elements and" elements "compound symbol elements examined."
-- We are done
Exit 0
--------------------------------------------------------------------------------
BadArgument:
Say "Incorrect file specification:" file
Exit 1
--------------------------------------------------------------------------------
Print:
class = element~category
from = element~from
to = element~to
Parse Var from fromLine fromCol
Parse Var to toLine toCol
Call Chunk "["Extent(element)"]"
Call Chunk (from == to)~?(" >"," ")
Call Chunk (element~ignored == 1)~?("X"," ")
Call Chunk (element~isAssigned)~?("A"," ")
If class \== .EL.RESOURCE_DATA Then value = element~value
Else value = "[... resource data ...]"
Call Chunk " '"value"'"
If class == .EL.TAKEN_CONSTANT Then Do
Say " ("AorAN(ConstantName(element~subCategory))" taken_constant)"
End
Else Do
Say " ("AorAN(CategoryName(element~category))")"
If element < .ALL.COMPOUND_VARIABLES Then Call Compound
End
If value == .Nil Then Do
Say "Unexpected .Nil value for element condition."
Exit 1
End
Return
--------------------------------------------------------------------------------
Extent: Procedure
Use Arg element
from = element~from
to = element~to
Parse Var from fromLine fromCol
Parse Var to toLine toCol
Return Right(fromLine,5) Right(fromCol,3)":"Right(toLine,5) Right(toCol,3)
--------------------------------------------------------------------------------
Compound:
Do part Over element~parts
elements += 1
Say " "Extent(part)" -> '"part~value"' ("||,
AorAN(.Parser.CategoryName[part~category])")"
End
Return
--------------------------------------------------------------------------------
AorAN:
If "AEIOU"~contains(Arg(1)[1]) Then Return "an" Arg(1)
Return "a" Arg(1)
--------------------------------------------------------------------------------
Chunk:
Call CharOut , Arg(1)
Return
--------------------------------------------------------------------------------
-- Standard Rexx Parser error handler --
--------------------------------------------------------------------------------
Syntax:
co = condition("O")
If co~code \== 98.900 Then Do
Say "Error" co~code "in" co~program", line" co~position":"
Raise Propagate
End
additional = Condition("A")
Say additional[1]":"
line = Additional~lastItem~position
Say Right(line,6) "*-*" source[line]
Say Copies("-",80)
Say co~stackFrames~makeArray
additional = additional~lastItem
Raise Syntax (additional~code) Additional (additional~additional)
Exit
--------------------------------------------------------------------------------
-- Help text --
--------------------------------------------------------------------------------
::Resource Help end "::End"
Usage: myName [options] FILE
Transform FILE into a list of elements and list them.
Options:
--tutor Enable TUTOR-flavored Unicode
-u, --unicode Enable TUTOR-flavored Unicode
The 'myname' program is part of the Rexx Parser package, and is distributed
under the Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0).
Copyright (c) 2024, 2025 Josep Maria Blasco <josep.maria.blasco@epbcn.com>.
::End