How to create same tree except leaves? - parsing

I am making a parser for BGP Communities. I decided to make it with Antlr but I am totally new. This is my input:
NO_EXPORT do not to NTT
NO_EXPORT set to CNN
NO_EXPORT prepend except CNN
NO_EXPORT do not to CNN
LOCAL_PREFERENCE do not to NTT
LOCAL_PREFERENCE do not to CNN
That is my code:
expression
: action*
;
action
: no_export+
| local_preference+
| as_padding+
;
no_export
: 'NO_EXPORT' sentencenevdn+
| 'NO_EXPORT' sentencenevs+
| 'NO_EXPORT' sentencenevp+
;
local_preference
: ('LOCAL_PREFERENCE' sentencelp)+
;
as_padding
: ('AS_PADDING' sentenceap)+
;
sentencenevdn
: 'do not' prepdest+
;
sentencenevs
: ('set' prepdest)+
;
sentencenevp
: ('prepend' prepdest)+
;
sentencelp
: (verbs prepdest)+
;
sentenceap
: (verbs prepdest)+
;
verbs
: ('do not'|'set'|'prepend')+
;
prepdest
: 'to' dest+
| 'except' dest+
;
dest
: DESTINATION
;
This is output:
As you can see the first and the fourth "no_export" are the same execpt the "dest". I would like them to be the same child and this dest have two leaves: NTT and CNN
Anyone can help me? Thanks

Antlr is a tool primarily to lex/parse some input (syntactically), not to interpret the semantics. The resulting parse tree reflects the structure of your input data syntactically, not its semantic meaning. You are trying to gather pieces of information from different places in your input, however, to interpret them semantically.
Instead, simply use a second step when you have the tree above. Antlr will generate visitors or listeners for you if desired (use the -visitor or -listener command line options), with which you can easily traverse the tree to extract and collect your desired data in any data structure you convenient for you.

Related

Example of combinatorial FSM?

On the Wikipedia page of Finite State Machines it shows a graphic of the automata types:
I've never heard of combinational logic being included in the automata theory, normally just the Chomsky hierarchy, which stars with FSM. How then would combinational logic be written using a state machine?
For example, if we have an AND gate, I'd see it in a circuit diagram as something like:
______
A ------- | |
| AND |------- C
B ------- |______|
And the states would be: 1(A) & 1(B) --> 1(C), 1&0->0, 0&1->0, 0&0->0. But this involves two initial states rather than one, and also the input to a 'gate' is the combination of two inputs rather than one, so how would this be shown using a FSM? I suppose it could be possible doing something like the following -- with the input symbols being {0,1} and the output {0,1} like a Moore machine.
1 1
s0 ----> s2 -----> s3:1
| | 0
------> s3:0 --0,1--|
0 ^----------|
But this seems a bit useless to me so maybe I'm getting it wrong, what then would be a proper way to model Combinational logic in a state diagram?
Here would be a simpler way to diagram the above, where the Input and Output states are either ON (1) or OFF (0) to make it more intuitive.

What is RDROP in Forth?

I'm new to Forth and I'm using SwiftForth. I am looking for a way to read a matrix from file as described here Writing a text file into an array on Forth, but rdrop is not recognised. Is this exclusive to Gforth or is it part of a library? If it's a library, what are the steps needed to use it?
RDROP is a well known but not standardized word.
This word can be defined in the following way:
: rdrop ( R: x -- ) postpone r> postpone drop ; immediate
A conditional definition in a portable library can look like the following:
[UNDEFINED] RDROP [IF]
: RDROP ( R: x -- ) POSTPONE R> POSTPONE DROP ; IMMEDIATE
[THEN]
"rdrop" can also be defined as followed, although it is not strictly standards compliant:
: rdrop r> r> drop >r ;
This has the advantage that is can be used as an execution token and it will not attempt to compile words into the dictionary, although it will not likely do anything sensible.

New lines in word definition using interpreter directives of Gforth

I am using the interpreter directives (non ANS standard) control structures of Gforth as described in the manual section 5.13.4 Interpreter Directives. I basically want to use the loop words to create a dynamically sized word containing literals. I came up with this definition for example:
: foo
[ 10 ] [FOR]
1
[NEXT]
;
Yet this produces an Address alignment exception after the [FOR] (yes, I know you should not use a for loop in Forth at all. This is just for an easy example).
In the end it turned out that you have to write loops as one-liners in order to ensure their correct execution. So doing
: foo [ 10 [FOR] ] 1 [ [NEXT] ] ;
instead works as intended. Running see foo yields:
: foo
1 1 1 1 1 1 1 1 1 1 1 ; ok
which is exactly what I want.
Is there a way to get new lines in the word definition? The words I would like to write are way more complex, and for a presentation I would need them better formatted.
It would really be best to use an immediate word instead. For example,
: ones ( n -- ) 0 ?do 1 postpone literal loop ; immediate
: foo ( -- ten ones ) [ 10 ] ones ;
With SEE FOO resulting in the same as your example. With POSTPONE, especially with Gforth's ]] .. [[ syntax, the repeated code can be as elaborate as you like.
A multiline [FOR] would need to do four things:
Use REFILL to read in subsequent lines.
Save the read-in lines, because you'll need to evaluate them one by one to preserve line-expecting parsing behavior (such as from comments: \ ).
Stop reading in lines, and loop, when you match the terminating [NEXT].
Take care to leave >IN right after the [NEXT] so that interpretation can continue normally.
You might still run into issues with some code, like code checking SOURCE-ID.
For an example of using REFILL to parse across multiple lines, here's code from a recent posting from CLF, by Gerry:
: line, ( u1 caddr2 u2 -- u3 )
tuck here swap chars dup allot move +
;
: <text>  ( "text" -- caddr u )
here 0
begin
refill
while
bl word count s" </text>" compare
while
0 >in ! source line, bl c, 1+
repeat then
;
This collects everything between <text> and a </text> that's on its own line, as with a HERE document, while also adding spaces. To save the individual lines for [FOR] in an easy way, I'd recommend leaving 0 as a sentinel on the data stack and then drop SAVE-MEM 'd lines on top of it.

Cypher request to extract genealogy

I'm parsing a book within neo4j and I'd like to extract genealogy out of it I have sentences like :
"A begat B,C and D"
"X begat Y, and Y begat Z, ..."
and I store that as
(A:word)-[:subj]->(begat:word)-[:obj]-> (B:word)
(A:word)-[:subj]->(begat:word)-[:comp]-> (C:word)
(X:word)-[:subj]->(begat:word)-[:obj]-> (Y:word)
(Y:word)-[:subj]->(begat:word)-[:obj]-> (Z:word)
(X:word)-[:NNP]->(sentence:word)
(Y:word)-[:NNP]->(sentence:word)
(Z:word)-[:NNP]->(sentence:word)
(begat:word)-[:VBG]->(sentence:word)
How could I write my cypher request so that neo4j server visualization give me a tree instead of one "begat" node with all the other ones linking to it ? My genealogy is on several sentences and when linking word together I add the sentenceId to the relationship maybe we could use that.
The result would look like
A
______|_____
| | |
B C D
|
X
|
Y
|
Z
One more info the words are stored only once to avoid memory consumption.
Here is a sample of my data :
http://console.neo4j.org/r/xzsazf
Many thanks

Transform an Abstract Syntax Tree (AST) in F#

I am trying to design an AST for a decision logic table. One of the things I would like to be able to do with the discriminated union that represents my AST is transform parts of it for different reasons. For clarity I will give you an example
Decision Logic Table
# VAR = 10 ;Y;
The above can be read as there is one rule and the condition VAR = 10 enters this rule with a Y entry.
Abstract Syntax Tree Definition (simplified for this example)
type expression =
| Value of double
| Variable of string
| Equality of expression * expression
type entry =
| Entry of string
type entries =
| Entries of entry list
type conditional =
| ConditionEntries of expression * entries
type condition
| Condition of expression * string
type rule =
| Rule of condition list
Rendered (before transform)
ConditionEntries(
Equality(
Variable("VAR"),
Value(10.0)),
Entries(["Y"]))
Rendered (after transform)
Rule(
Condition(
Equality(
Variable("VAR"),
Value(10.0)
),
Entry("Y")
)
)
Now what I would like to do is transform the above tree to expand the rules that are represented in the entries. My thinking was I could use a recursive function and pattern-matching to do this but I am having a little trouble wrapping my head around it right now.
I guess in essence what I am trying to do is whenever I see a ConditionEntries node, I want to emit a new Rule for every string in the Entries list where the Condition is combined with the Entry. Does that make any sense?
Thanks in advance for any advice.
p.s. I haven't quite tried to compile the above example, so please forgive any grammatical errors.
Hmm, based on your AST, which is awfully broken up, here is a tranform function which produces the output from input you desire (though it's not recursive, just uses List.map with some pattern matching. expression is your only recursive type but it doesn't look like you want to process it recursively?):
let ex1 =
ConditionEntries(
Equality(
Variable("VAR"),
Value(10.0)),
Entries([Entry("Y")]))
let ex2 =
ConditionEntries(
Equality(
Variable("VAR"),
Value(10.0)),
Entries([Entry("X");Entry("Y");Entry("Z")]))
let transform ces =
match ces with
| ConditionEntries(x, Entries(entries)) ->
entries
|> List.map (function Entry(entry) -> Condition(x, entry))
//FSI output:
> transform ex1;;
val it : condition list =
[Condition (Equality (Variable "VAR",Value 10.0),"Y")]
> transform ex2;;
val it : condition list =
[Condition (Equality (Variable "VAR",Value 10.0),"X");
Condition (Equality (Variable "VAR",Value 10.0),"Y");
Condition (Equality (Variable "VAR",Value 10.0),"Z")]

Resources